00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __SYNC_W32_H__
00012 #define __SYNC_W32_H__
00013
00014
00015 #ifdef SET_NULL_DACL
00016 class FASTDB_DLL_ENTRY dbNullSecurityDesciptor {
00017 public:
00018 SECURITY_DESCRIPTOR sd;
00019 SECURITY_ATTRIBUTES sa;
00020
00021 dbNullSecurityDesciptor() {
00022 InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
00023 SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
00024 sa.nLength = sizeof(sa);
00025 sa.bInheritHandle = TRUE;
00026 sa.lpSecurityDescriptor = &sd;
00027 }
00028
00029 static dbNullSecurityDesciptor instance;
00030 };
00031 #define FASTDB_SECURITY_ATTRIBUTES &dbNullSecurityDesciptor::instance.sa
00032 #else
00033 #define FASTDB_SECURITY_ATTRIBUTES NULL
00034 #endif
00035
00036 class FASTDB_DLL_ENTRY dbMutex {
00037 CRITICAL_SECTION cs;
00038 bool initialized;
00039 public:
00040 dbMutex() {
00041 InitializeCriticalSection(&cs);
00042 initialized = true;
00043 }
00044 ~dbMutex() {
00045 DeleteCriticalSection(&cs);
00046 initialized = false;
00047 }
00048 bool isInitialized() {
00049 return initialized;
00050 }
00051 void lock() {
00052 if (initialized) {
00053 EnterCriticalSection(&cs);
00054 }
00055 }
00056 void unlock() {
00057 if (initialized) {
00058 LeaveCriticalSection(&cs);
00059 }
00060 }
00061 };
00062
00063 #define thread_proc WINAPI
00064
00065 class FASTDB_DLL_ENTRY dbThread {
00066 HANDLE h;
00067 public:
00068 typedef void (thread_proc* thread_proc_t)(void*);
00069
00070 void create(thread_proc_t f, void* arg) {
00071 DWORD threadid;
00072 h = CreateThread(FASTDB_SECURITY_ATTRIBUTES, 0, LPTHREAD_START_ROUTINE(f), arg,
00073 0, &threadid);
00074 }
00075 enum ThreadPriority {
00076 THR_PRI_LOW,
00077 THR_PRI_HIGH
00078 };
00079
00080 void setPriority(ThreadPriority pri) {
00081 SetThreadPriority(h, pri == THR_PRI_LOW ? THREAD_PRIORITY_IDLE : THREAD_PRIORITY_HIGHEST);
00082 }
00083
00084 void join() {
00085 WaitForSingleObject(h, INFINITE);
00086 CloseHandle(h);
00087 h = NULL;
00088 }
00089 void detach() {
00090 if (h != NULL) {
00091 CloseHandle(h);
00092 h = NULL;
00093 }
00094 }
00095 dbThread() {
00096 h = NULL;
00097 }
00098 ~dbThread() {
00099 if (h != NULL) {
00100 CloseHandle(h);
00101 }
00102 }
00103 static int numberOfProcessors() {
00104 #ifdef PHAR_LAP
00105 return 1;
00106 #else
00107 SYSTEM_INFO sysinfo;
00108 GetSystemInfo(&sysinfo);
00109 return sysinfo.dwNumberOfProcessors;
00110 #endif
00111 }
00112 };
00113
00114 class FASTDB_DLL_ENTRY dbProcessId {
00115 DWORD tid;
00116 public:
00117 bool operator != (dbProcessId const& other) const {
00118 return tid != other.tid;
00119 }
00120
00121 void clear() {
00122 tid = 0;
00123 }
00124
00125 static dbProcessId getCurrent() {
00126 dbProcessId curr;
00127 curr.tid = GetCurrentThreadId();
00128 return curr;
00129 }
00130 };
00131
00132 class FASTDB_DLL_ENTRY dbInitializationMutex {
00133 HANDLE m;
00134 public:
00135 enum initializationStatus {
00136 InitializationError,
00137 AlreadyInitialized,
00138 NotYetInitialized
00139 };
00140 initializationStatus initialize(char const* name) {
00141 initializationStatus status;
00142 m = CreateMutex(FASTDB_SECURITY_ATTRIBUTES, true, name);
00143 if (GetLastError() == ERROR_ALREADY_EXISTS) {
00144 status = WaitForSingleObject(m, INFINITE) == WAIT_OBJECT_0
00145 ? AlreadyInitialized : InitializationError;
00146 ReleaseMutex(m);
00147 } else if (m != NULL) {
00148 status = NotYetInitialized;
00149 } else {
00150 status = InitializationError;
00151 }
00152 return status;
00153 }
00154 void done() {
00155 ReleaseMutex(m);
00156 }
00157 bool close() {
00158 CloseHandle(m);
00159 return false;
00160 }
00161 void erase() {
00162 close();
00163 }
00164 dbInitializationMutex() {
00165 m = NULL;
00166 }
00167 };
00168
00169
00170 const int dbMaxSemValue = 1000000;
00171
00172
00173 class FASTDB_DLL_ENTRY dbSemaphore {
00174 protected:
00175 HANDLE s;
00176 public:
00177 bool wait(unsigned msec = INFINITE) {
00178 int rc = WaitForSingleObject(s, msec);
00179 assert(rc == WAIT_OBJECT_0 || rc == WAIT_TIMEOUT);
00180 return rc == WAIT_OBJECT_0;
00181 }
00182 void signal(unsigned inc = 1) {
00183 if (inc != 0) {
00184 ReleaseSemaphore(s, inc, NULL);
00185 }
00186 }
00187 void reset() {
00188 while (WaitForSingleObject(s, 0) == WAIT_OBJECT_0);
00189 }
00190 bool open(char const* name, unsigned initValue = 0) {
00191 s = CreateSemaphore(FASTDB_SECURITY_ATTRIBUTES, initValue, dbMaxSemValue, name);
00192 return s != NULL;
00193 }
00194 void close() {
00195 CloseHandle(s);
00196 }
00197 void erase() {
00198 close();
00199 }
00200 dbSemaphore() {
00201 s = NULL;
00202 }
00203 };
00204
00205 class FASTDB_DLL_ENTRY dbEvent {
00206 protected:
00207 HANDLE e;
00208 public:
00209 bool wait(unsigned msec = INFINITE) {
00210 int rc = WaitForSingleObject(e, msec);
00211 assert(rc == WAIT_OBJECT_0 || rc == WAIT_TIMEOUT);
00212 return rc == WAIT_OBJECT_0;
00213 }
00214 void signal() {
00215 SetEvent(e);
00216 }
00217 void reset() {
00218 ResetEvent(e);
00219 }
00220 bool open(char const* name, bool signaled = false) {
00221 e = CreateEvent(FASTDB_SECURITY_ATTRIBUTES, true, signaled, name);
00222 return e != NULL;
00223 }
00224 void close() {
00225 CloseHandle(e);
00226 }
00227 void erase() {
00228 close();
00229 }
00230 dbEvent() {
00231 e = NULL;
00232 }
00233 };
00234
00235 class FASTDB_DLL_ENTRY dbLocalSemaphore : public dbSemaphore {
00236 public:
00237 bool wait(dbMutex& mutex, time_t timeoutMsec) {
00238 mutex.unlock();
00239 int rc = WaitForSingleObject(s, timeoutMsec);
00240 assert(rc == WAIT_OBJECT_0 || rc == WAIT_TIMEOUT);
00241 mutex.lock();
00242 return rc == WAIT_OBJECT_0;
00243 }
00244 void wait(dbMutex& mutex) {
00245 mutex.unlock();
00246 int rc = WaitForSingleObject(s, INFINITE);
00247 assert(rc == WAIT_OBJECT_0);
00248 mutex.lock();
00249 }
00250 bool open(unsigned initValue = 0) {
00251 return dbSemaphore::open(NULL, initValue);
00252 }
00253 };
00254
00255 class FASTDB_DLL_ENTRY dbLocalEvent : public dbEvent {
00256 public:
00257 bool wait(dbMutex& mutex, time_t timeoutMsec) {
00258 mutex.unlock();
00259 int rc = WaitForSingleObject(e, timeoutMsec);
00260 assert(rc == WAIT_OBJECT_0 || rc == WAIT_TIMEOUT);
00261 mutex.lock();
00262 return rc == WAIT_OBJECT_0;
00263 }
00264 void wait(dbMutex& mutex) {
00265 mutex.unlock();
00266 int rc = WaitForSingleObject(e, INFINITE);
00267 assert(rc == WAIT_OBJECT_0);
00268 mutex.lock();
00269 }
00270 bool open(bool signaled = false) {
00271 return dbEvent::open(NULL, signaled);
00272 }
00273 };
00274
00275 template<class T>
00276 class dbThreadContext {
00277 unsigned int index;
00278 public:
00279 T* get() {
00280 return (T*)TlsGetValue(index);
00281 }
00282 void set(T* value) {
00283 TlsSetValue(index, value);
00284 }
00285 dbThreadContext() {
00286 index = TlsAlloc();
00287 assert(index != TLS_OUT_OF_INDEXES);
00288 }
00289 ~dbThreadContext() {
00290 TlsFree(index);
00291 }
00292 };
00293
00294 template<class T>
00295 class dbSharedObject {
00296 T* ptr;
00297 HANDLE h;
00298 public:
00299
00300 bool open(char* name) {
00301 #ifdef NO_MMAP
00302 ptr = new T();
00303 #else
00304 h = CreateFileMapping(INVALID_HANDLE_VALUE,
00305 FASTDB_SECURITY_ATTRIBUTES, PAGE_READWRITE, 0,
00306 sizeof(T), name);
00307 if (h == NULL) {
00308 return false;
00309 }
00310 ptr = (T*)MapViewOfFile(h, FILE_MAP_ALL_ACCESS, 0, 0, 0);
00311 if (ptr == NULL) {
00312 CloseHandle(h);
00313 return false;
00314 }
00315 #endif
00316 return true;
00317 }
00318
00319 T* get() { return ptr; }
00320
00321 void close() {
00322 #ifdef NO_MMAP
00323 delete[] ptr;
00324 #else
00325 UnmapViewOfFile(ptr);
00326 CloseHandle(h);
00327 #endif
00328 }
00329 void erase() {
00330 close();
00331 }
00332 dbSharedObject() {
00333 ptr = NULL;
00334 h = NULL;
00335 }
00336 };
00337
00338 typedef long sharedsem_t;
00339
00340 class FASTDB_DLL_ENTRY dbGlobalCriticalSection {
00341 HANDLE event;
00342 sharedsem_t* count;
00343
00344 public:
00345 void enter() {
00346 if (InterlockedDecrement(count) != 0) {
00347
00348 int rc = WaitForSingleObject(event, INFINITE);
00349 assert (rc == WAIT_OBJECT_0);
00350 }
00351 }
00352
00353 void leave() {
00354 if (InterlockedIncrement(count) <= 0) {
00355
00356 SetEvent(event);
00357 }
00358 }
00359
00360 bool open(char const* name, long* count) {
00361 this->count = count;
00362 event = OpenEvent(EVENT_ALL_ACCESS, FALSE, name);
00363 return event != NULL;
00364 }
00365 bool create(char const* name, long* count) {
00366 this->count = count;
00367 *count = 1;
00368 event = CreateEvent(FASTDB_SECURITY_ATTRIBUTES, false, false, name);
00369 return event != NULL;
00370 }
00371 void close() {
00372 CloseHandle(event);
00373 }
00374 void erase() {
00375 close();
00376 }
00377 dbGlobalCriticalSection() {
00378 event = NULL;
00379 }
00380
00381 };
00382
00383 #endif //__SYNC_W32_H__