Main Page | Class Hierarchy | Class List | File List | Class 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 
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             // another process is in critical section
00348             int rc = WaitForSingleObject(event, INFINITE);
00349             assert (rc == WAIT_OBJECT_0);
00350         }
00351     }
00352 
00353     void leave() { 
00354         if (InterlockedIncrement(count) <= 0) { 
00355             // some other processes try to enter critical section
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__

Generated on Thu Feb 12 13:04:48 2004 for FastDB by doxygen 1.3.5