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