Main Page   Class Hierarchy   Compound List   File List   Compound Members  

sync_w32.h

00001 //-< SYNC_W32.H >----------------------------------------------------*--------*
00002 // FastDB                    Version 1.0         (c) 1999  GARRET    *     ?  *
00003 // (Main Memory Database Management System)                          *   /\|  *
00004 //                                                                   *  /  \  *
00005 //                          Created:     20-Nov-98    K.A. Knizhnik  * / [] \ *
00006 //                          Last update: 20-Dec-98    K.A. Knizhnik  * GARRET *
00007 //-------------------------------------------------------------------*--------*
00008 // Intertask synchonization primitives
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             // another process is in critical section
00414             int rc = WaitForSingleObject(event, INFINITE);
00415             assert (rc == WAIT_OBJECT_0);
00416         }
00417     }
00418 
00419     void leave() { 
00420         if (InterlockedIncrement(count) <= 0) { 
00421             // some other processes try to enter critical section
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__

Generated on Mon Oct 23 13:23:58 2006 for FastDB by doxygen1.2.18