Main Page   Class Hierarchy   Compound List   File List   Compound Members  

sync_unix.h

00001 //-< SYNC_UNIX.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 for Unix platforms
00009 //-------------------------------------------------------------------*--------*
00010 
00011 #ifndef __SYNC_UNIX_H__
00012 #define __SYNC_UNIX_H__
00013 
00014 // Standard includes for all Unix platforms
00015 #include <unistd.h>
00016 #include <string.h>
00017 #include <fcntl.h>
00018 #include <sys/time.h>
00019 #include <sys/types.h>
00020 #include <assert.h>
00021 #include <errno.h>
00022 
00023 #if !defined(USE_POSIX_SEMAPHORES) || !defined(USE_POSIX_MMAP) || !USE_POSIX_MMAP
00024 #include <sys/ipc.h> 
00025 extern char const* keyFileDir; // default value: "/tmp/" 
00026 #endif
00027 
00028 #if defined(USE_POSIX_SEMAPHORES)
00029 #include <semaphore.h>  // For POSIX style semaphores
00030 #else
00031 #include <sys/sem.h>    // For SysV style semaphores
00032 #endif
00033 
00034 #if defined(USE_POSIX_MMAP) && USE_POSIX_MMAP
00035 #include <sys/mman.h>   // For mmap()
00036 #else
00037 #include <sys/shm.h>    
00038 #include <sys/mman.h>
00039 #endif
00040 
00041 BEGIN_FASTDB_NAMESPACE
00042 
00043 #define thread_proc
00044 
00046 // If this system uses pthread based threads, then define
00047 //   dbMutex(), dbThread(), dbLocalEvent(), etc as pthread-based implemenations
00048 
00049 #ifndef NO_PTHREADS
00050 
00051 // Use pthread based implementation
00052 #include <pthread.h>
00053 
00054 class dbMutex { 
00055     friend class dbLocalEvent;
00056     friend class dbLocalSemaphore;
00057     pthread_mutex_t cs;
00058     bool            initialized;
00059   public:
00060     dbMutex() {
00061         int rc = pthread_mutex_init(&cs, NULL);
00062         assert(rc == 0);
00063         initialized = true;
00064     }
00065     ~dbMutex() {
00066         int rc = pthread_mutex_destroy(&cs);
00067         assert(rc == 0);
00068         initialized = false;
00069     }
00070     bool isInitialized() { 
00071         return initialized;
00072     }
00073     void lock() {
00074         if (initialized) { 
00075             int rc = pthread_mutex_lock(&cs);
00076             assert(rc == 0);
00077         }
00078     }
00079     void unlock() {
00080         if (initialized) { 
00081             int rc = pthread_mutex_unlock(&cs);
00082             assert(rc == 0);
00083         }
00084     }
00085 };
00086 
00087 
00088 const size_t dbThreadStackSize = 1024*1024;
00089 
00090 class dbThread { 
00091     pthread_t thread;
00092   public:
00093     typedef void (thread_proc* thread_proc_t)(void*);
00094     
00095     static void sleep(time_t sec) { 
00096         ::sleep(sec);
00097     }
00098 
00099     void create(thread_proc_t f, void* arg) {
00100         pthread_attr_t attr;
00101         pthread_attr_init(&attr);
00102 #if !defined(__linux__)
00103         pthread_attr_setstacksize(&attr, dbThreadStackSize);
00104 #endif
00105 #if defined(_AIX41)
00106         // At AIX 4.1, 4.2 threads are by default created detached
00107         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_UNDETACHED);
00108 #endif
00109         pthread_create(&thread, &attr, (void*(*)(void*))f, arg);
00110         pthread_attr_destroy(&attr);
00111     }
00112 
00113     void join() { 
00114         void* result;
00115         pthread_join(thread, &result);
00116     }
00117     void detach() { 
00118         pthread_detach(thread);
00119     }
00120 
00121     enum ThreadPriority { 
00122         THR_PRI_LOW, 
00123         THR_PRI_HIGH
00124     };
00125     void setPriority(ThreadPriority pri) { 
00126 #if defined(PRI_OTHER_MIN) && defined(PRI_OTHER_MAX)
00127         struct sched_param sp;
00128         sp.sched_priority = pri == THR_PRI_LOW ? PRI_OTHER_MIN : PRI_OTHER_MAX;
00129         pthread_setschedparam(thread, SCHED_OTHER, &sp); 
00130 #endif
00131     }
00132 
00133     static int numberOfProcessors();
00134 };
00135 
00136 
00137 class dbLocalEvent { 
00138     pthread_cond_t   cond;
00139     int              signaled;
00140   public:
00141     void wait(dbMutex& mutex) { 
00142         while (!signaled) { 
00143             pthread_cond_wait(&cond, &mutex.cs);
00144         }
00145     }
00146     bool wait(dbMutex& mutex, time_t timeout) {
00147         if (!signaled) { 
00148             struct timespec abs_ts; 
00149 #ifdef PTHREAD_GET_EXPIRATION_NP
00150             struct timespec rel_ts; 
00151             rel_ts.tv_sec = timeout/1000; 
00152             rel_ts.tv_nsec = timeout%1000*1000000;
00153             pthread_get_expiration_np(&rel_ts, &abs_ts);
00154 #else
00155             struct timeval cur_tv;
00156             gettimeofday(&cur_tv, NULL);
00157             abs_ts.tv_sec = cur_tv.tv_sec + timeout/1000; 
00158             abs_ts.tv_nsec = cur_tv.tv_usec*1000 + timeout%1000*1000000;
00159             if (abs_ts.tv_nsec > 1000000000) { 
00160                 abs_ts.tv_nsec -= 1000000000;
00161                 abs_ts.tv_sec += 1;
00162             }
00163 #endif
00164             do { 
00165                 int rc = pthread_cond_timedwait(&cond, &mutex.cs, &abs_ts);
00166                 if (rc != 0) {
00167                     return false;
00168                 }
00169             } while (!signaled);
00170 
00171         }
00172         return true;
00173     }
00174     void signal() {
00175         signaled = true;
00176         pthread_cond_broadcast(&cond);
00177     }
00178     void reset() {
00179         signaled = false;
00180     }
00181     void open(bool initValue = false) { 
00182         signaled = initValue;
00183         pthread_cond_init(&cond, NULL);
00184     }
00185     void close() {
00186         pthread_cond_destroy(&cond);
00187     }
00188 };
00189 
00190 class dbLocalSemaphore { 
00191     pthread_cond_t   cond;
00192     int              count;
00193   public:
00194     void wait(dbMutex& mutex) { 
00195         while (count == 0) { 
00196             pthread_cond_wait(&cond, &mutex.cs);
00197         }
00198         count -= 1;
00199     }
00200     bool wait(dbMutex& mutex, time_t timeout) {
00201         if (count == 0) { 
00202             struct timespec abs_ts; 
00203 #ifdef PTHREAD_GET_EXPIRATION_NP
00204             struct timespec rel_ts; 
00205             rel_ts.tv_sec = timeout/1000; 
00206             rel_ts.tv_nsec = timeout%1000*1000000;
00207             pthread_get_expiration_np(&rel_ts, &abs_ts);
00208 #else
00209             struct timeval cur_tv;
00210             gettimeofday(&cur_tv, NULL);
00211             abs_ts.tv_sec = cur_tv.tv_sec + timeout/1000; 
00212             abs_ts.tv_nsec = cur_tv.tv_usec*1000 + timeout%1000*1000000;
00213             if (abs_ts.tv_nsec > 1000000000) { 
00214                 abs_ts.tv_nsec -= 1000000000;
00215                 abs_ts.tv_sec += 1;
00216             }
00217 #endif
00218             do { 
00219                 int rc = pthread_cond_timedwait(&cond, &mutex.cs, &abs_ts);
00220                 if (rc != 0) { 
00221                     return false;
00222                 }
00223             } while (count == 0);
00224         }
00225         count -= 1;
00226         return true;
00227     }
00228     void signal(unsigned inc = 1) {
00229         count += inc;
00230         if (inc > 1) { 
00231             pthread_cond_broadcast(&cond);
00232         } else if (inc == 1) { 
00233             pthread_cond_signal(&cond);
00234         }
00235     }
00236     void open(unsigned initValue = 0) { 
00237         pthread_cond_init(&cond, NULL);
00238         count = initValue;
00239     }
00240     void close() {
00241         pthread_cond_destroy(&cond);
00242     }
00243 };
00244 
00245 template<class T> 
00246 class dbThreadContext { 
00247     pthread_key_t key;
00248   public:
00249     T* get() { 
00250         return (T*)pthread_getspecific(key);
00251     }
00252     void set(T* value) { 
00253         pthread_setspecific(key, value);
00254     }
00255     dbThreadContext() { 
00256         pthread_key_create(&key, NULL);
00257     }
00258     ~dbThreadContext() { 
00259         pthread_key_delete(key);
00260     }
00261 };
00262 
00263 class dbProcessId { 
00264     int       pid;
00265     pthread_t tid;
00266   public:
00267     bool operator != (dbProcessId const& other) const { 
00268         return pid != other.pid || tid != other.tid;
00269     }
00270 
00271     void clear() { 
00272         pid = 0;
00273         tid = 0;
00274     }
00275 
00276     static dbProcessId getCurrent() {
00277         dbProcessId curr;
00278         curr.pid = getpid();
00279         curr.tid = pthread_self();
00280         return curr;
00281     }
00282 };
00283 
00284 #else // NO_PTHREAD
00285 
00286 // Non pthread based threads, mutexes, etc.
00287 // Maps to skeleton  functions, this implementation isn't using threads.
00288 
00289 class dbMutex {
00290     bool initialized;
00291 
00292    public:
00293     dbMutex() {
00294         initialized = true;
00295     }
00296 
00297     ~dbMutex() { 
00298         initialized = false;
00299     }
00300 
00301     bool isInitialized() { 
00302         return initialized;
00303     }
00304 
00305     void lock() {}
00306     void unlock() {}
00307 };
00308 
00309 class dbThread { 
00310   public:
00311     typedef void (thread_proc* thread_proc_t)(void*);
00312     void create(thread_proc_t f, void* arg) { f(arg); }
00313     void join() {}
00314     void detach() {}
00315     enum ThreadPriority { 
00316         THR_PRI_LOW, 
00317         THR_PRI_HIGH
00318     };
00319     void setPriority(ThreadPriority pri) { }
00320     static int numberOfProcessors() { return 1; }
00321 };
00322 
00323 class dbLocalSemaphore { 
00324     int count;
00325   public:
00326     void wait(dbMutex&) { 
00327         assert (count > 0);
00328         count -= 1;
00329     }
00330     void signal(unsigned inc = 1) {
00331         count += inc;
00332     }
00333     void open(unsigned initValue = 0) {
00334         count = initValue;
00335     }
00336     void close() {}
00337 };
00338 
00339 class dbLocalEvent { 
00340     bool signaled;
00341   public:
00342     void wait(dbMutex&) { 
00343         assert(signaled);
00344     }
00345     bool wait(dbMutex& mutex, time_t timeout) {
00346         return true;
00347     }
00348     void signal() {
00349         signaled = true;
00350     }
00351     void reset() {
00352         signaled = false;
00353     }
00354     void open(bool initValue = false) {
00355         signaled = initValue;
00356     }
00357     void close() {}
00358 };
00359 
00360 template<class T>
00361 class dbThreadContext { 
00362     T* value;
00363   public:
00364     T* get() { 
00365         return value;
00366     }
00367     void set(T* value) { 
00368         this->value = value;
00369     }
00370     dbThreadContext() { value = NULL; }
00371 };
00372 
00373 
00374 class dbProcessId { 
00375     int       pid;
00376   public:
00377     bool operator != (dbProcessId const& other) const { 
00378         return pid != other.pid;
00379     }
00380     
00381     void clear() { 
00382         pid = 0;
00383     }
00384 
00385     static dbProcessId getCurrent() {
00386         dbProcessId curr;
00387         curr.pid = getpid();
00388         return curr;
00389     }
00390 };
00391 
00392 #endif // NO_PTHREAD
00393 
00394 
00395 #define INFINITE (~0U)
00396 
00397 
00398 #ifdef USE_POSIX_SEMAPHORES
00399 
00400 // Initialization Mutex using Posix based semaphores
00401 class dbInitializationMutex { 
00402     sem_t* sem;
00403   public: 
00404     enum initializationStatus { 
00405         InitializationError, 
00406         AlreadyInitialized,
00407         NotYetInitialized
00408     };
00409     initializationStatus initialize(char const* name) { 
00410         initializationStatus status;
00411         char* tmp = NULL;
00412         if (*name != '/') { 
00413             tmp = new char[strlen(name)+2];
00414             strcpy(tmp+1, name);
00415             *tmp = '/';
00416             name = tmp;
00417         }
00418         while (true) {
00419             sem = sem_open(name, 0);
00420             if (sem == SEM_FAILED) { 
00421                 if (errno == ENOENT) {
00422                     sem = sem_open(name, O_CREAT|O_EXCL, 0777, 0);
00423                     if (sem != SEM_FAILED) { 
00424                         status = NotYetInitialized;
00425                         break;
00426                     } else if (errno != EEXIST) { 
00427                         status = InitializationError;
00428                         break;
00429                     }
00430                 } else { 
00431                     status = InitializationError;
00432                     break;
00433                 }
00434             } else { 
00435                 status = (sem_wait(sem) == 0 && sem_post(sem) == 0) 
00436                     ? AlreadyInitialized : InitializationError;
00437                 break;
00438             }
00439         }
00440         delete[] tmp;
00441         return status;
00442     }
00443 
00444     void done() { 
00445         sem_post(sem);
00446     }
00447     bool close() {
00448         sem_close(sem);
00449         return false;
00450     }
00451     void erase() { 
00452         close();
00453     }
00454 };
00455 
00456 class dbSemaphore { 
00457   protected:
00458     sem_t* sem;
00459   public:
00460     void wait() { 
00461         int rc = sem_wait(sem);
00462         assert(rc == 0);
00463     }
00464 
00465     bool wait(unsigned msec) { 
00466 #ifdef POSIX_1003_1d
00467         struct timespec abs_ts;
00468         struct timeval  cur_tv;
00469         clock_gettime(CLOCK_REALTIME, &cur_tv);
00470         abs_ts.tv_sec = cur_tv.tv_sec + (msec + cur_tv.tv_usec / 1000) / 1000000; 
00471         abs_ts.tv_nsec = (msec + cur_tv.tv_usec / 1000) % 1000000 * 1000;
00472         int rc = sem_timedwait(sem, &abs_ts);
00473         if (rc < 0) { 
00474             assert(errno == ETIMEDOUT);
00475             return false;
00476         }
00477         return true;
00478 #else 
00479         int rc = sem_wait(sem);
00480         assert(rc == 0);
00481         return true;
00482 #endif  
00483     }
00484 
00485     void signal(unsigned inc = 1) {
00486         while (--inc > 0) { 
00487             sem_post(sem);
00488         }
00489     }
00490     void reset() { 
00491         while (sem_trywait(sem) == 0);
00492     }    
00493     bool open(char const* name, unsigned initValue = 0) {
00494         char* tmp = NULL;
00495         if (*name != '/') { 
00496             tmp = new char[strlen(name)+2];
00497             strcpy(tmp+1, name);
00498             *tmp = '/';
00499             name = tmp;
00500         }
00501         sem = sem_open(name, O_CREAT, 0777, initValue);
00502         delete[] tmp;
00503         return sem != NULL; 
00504     }
00505     void close() {
00506         sem_close(sem);
00507     }
00508     void erase() { 
00509         close();
00510     }
00511 };
00512 
00513 class dbEvent : public dbSemaphore { 
00514   public:
00515     void wait() { 
00516         dbSemaphore::wait();
00517         sem_post(sem);
00518     }
00519     bool wait(unsigned msec) { 
00520         if (dbSemaphore::wait(msec)) { 
00521             sem_post(sem);
00522             return true;
00523         }
00524         return false;
00525     }
00526     void signal() {
00527         while (sem_trywait(sem) == 0);
00528         sem_post(sem);
00529     }
00530     void reset() {
00531         while (sem_trywait(sem) == 0);
00532     }
00533     bool open(char const* name, bool signaled = false) {
00534         return dbSemaphore::open(name, (int)signaled);
00535     }
00536 };
00537 #else // USE_POSIX_SEMAPHORES
00538 
00539 class FASTDB_DLL_ENTRY dbWatchDog { 
00540     bool open(char const* name, int flags);
00541   public:
00542     bool watch();
00543     void close(); 
00544     bool open(char const* name);
00545     bool create(char const* name);
00546     int id;
00547 };
00548 
00549 // Define local implemenation of InitializationMutex in sync.cpp
00550 class dbInitializationMutex { 
00551     int semid;
00552   public: 
00553     enum initializationStatus { 
00554         InitializationError, 
00555         AlreadyInitialized,
00556         NotYetInitialized
00557     };
00558     initializationStatus initialize(char const* name);
00559     void done(); 
00560     bool close();
00561     void erase();
00562 };
00563 
00564 
00565 class dbSemaphore { 
00566     int s;
00567   public:
00568     bool wait(unsigned msec = INFINITE);
00569     void signal(unsigned inc = 1);
00570     bool open(char const* name, unsigned initValue = 0);
00571     void reset();
00572     void close();
00573     void erase();
00574 };
00575 
00576 class dbEvent { 
00577     int e;
00578   public:
00579     bool wait(unsigned msec = INFINITE);
00580     void signal();
00581     void reset();
00582     bool open(char const* name, bool signaled = false);
00583     void close();
00584     void erase();
00585 };
00586 #endif // USE_POSIX_SEMAPHORES
00587 
00588 
00589 // Define dbSharedObject and dbSharedMemory
00590 #if defined(USE_POSIX_MMAP) && USE_POSIX_MMAP
00591 
00592 // For POSIX dbSharedObject, we use mmap()
00593 template<class T>
00594 class dbSharedObject { 
00595     char* name;
00596     T*  ptr;
00597     int fd;
00598   public:
00599 
00600     dbSharedObject() { 
00601         name = NULL;
00602         ptr = NULL;
00603         fd = -1;
00604     }
00605 
00606     bool open(char* fileName) { 
00607         delete[] name;
00608         name = new char[strlen(fileName) + 1];
00609         strcpy(name, fileName);
00610         fd = ::open(fileName, O_RDWR|O_CREAT, 0777);
00611         if (fd < 0) { 
00612             return false;
00613         }
00614         if (ftruncate(fd, sizeof(T)) < 0) {
00615             ::close(fd);
00616             return false;
00617         }
00618         ptr = (T*)mmap(NULL,
00619                        DOALIGN(sizeof(T), 4096),
00620                        PROT_READ|PROT_WRITE,
00621                        MAP_SHARED,
00622                        fd,
00623                        0);
00624         if (ptr == MAP_FAILED) { 
00625             ptr = NULL;
00626             ::close(fd);
00627             return false;
00628         }
00629         return true;
00630     }
00631 
00632     T* get() { return ptr; }
00633 
00634     void close() { 
00635         if (ptr != NULL) { 
00636             munmap((char*)ptr, DOALIGN(sizeof(T), 4096));
00637         }
00638         if (fd > 0) { 
00639             ::close(fd);
00640         }
00641     }
00642     void erase() {
00643         close();
00644         unlink(name);   
00645     }  
00646 
00647     ~dbSharedObject() { 
00648         delete[] name;
00649     }
00650 };
00651 
00652 #else // USE_POSIX_MMAP
00653 
00654 // Non POSIX, internal implementations of SharedMemory and SharedObject
00655 extern char const* keyFileDir; // default value: "/tmp/" 
00656 class dbSharedMemory { 
00657   protected:
00658     char*  ptr;
00659     int    shm;
00660 
00661   public:
00662     bool  open(char const* name, size_t size); 
00663     void  close();
00664     void  erase(); 
00665     char* get_base() { 
00666         return ptr;
00667     }
00668 };
00669 
00670 template<class T>
00671 class dbSharedObject : public dbSharedMemory { 
00672   public:
00673     bool open(char* name) { 
00674         return dbSharedMemory::open(name, sizeof(T));
00675     }
00676     T* get() { return (T*)ptr; }
00677 };
00678 
00679 #endif
00680 
00682 // Define dBGlobalCriticalSection for various platforms
00683 
00684 // QNX uses a pthread based mutex for its implementation
00685 //     Use only if pthread support is also enabled, else we'll use the default case
00686 #if defined(__QNX__) && !defined(NO_PTHREADS)
00687 typedef pthread_mutex_t sharedsem_t;
00688 
00689 class dbGlobalCriticalSection { 
00690     pthread_mutexattr_t attr;
00691     sharedsem_t* sem;
00692   public:
00693     void enter() {
00694         int rc = pthread_mutex_lock(sem);
00695         assert(rc == 0);
00696     }
00697     void leave() { 
00698         int rc = pthread_mutex_unlock(sem);
00699         assert(rc == 0);
00700     }
00701     bool open(char const*, sharedsem_t* shr) { 
00702         sem = shr;
00703         return true;
00704     }
00705     bool create(char const*, sharedsem_t* shr) { 
00706         sem = shr;
00707         pthread_mutexattr_init(&attr);
00708         pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
00709         pthread_mutexattr_setrecursive(&attr, PTHREAD_RECURSIVE_ENABLE);
00710         pthread_mutex_init(sem, &attr);
00711         return true;
00712     }
00713     void close() {}
00714     void erase() {
00715         pthread_mutex_destroy(sem);
00716     }
00717 };
00718 
00719 
00720 #elif defined(__osf__) && !defined(RECOVERABLE_CRITICAL_SECTION)
00721 // OSF uses "shared memory semaphores", located within a region mapped with mmap().
00722 #include <errno.h>
00723 typedef msemaphore sharedsem_t;
00724 
00725 class dbGlobalCriticalSection { 
00726     sharedsem_t* sem;
00727   public:
00728     void enter() { 
00729         int rc;
00730         while ((rc = msem_lock(sem, 0)) < 0 && errno == EINTR);
00731         assert(rc == 0);
00732     }
00733     void leave() { 
00734         int rc = msem_unlock(sem, 0);
00735         assert(rc == 0);        
00736     }
00737     bool open(char const*, sharedsem_t* shr) { 
00738         sem = shr;
00739         return true;
00740     }
00741     bool create(char const*, sharedsem_t* shr) { 
00742         sem = shr;
00743         msem_init(shr, MSEM_UNLOCKED);
00744         return true;
00745     }
00746     void close() {}
00747     void erase() {
00748         msem_remove(sem);
00749     }
00750 };
00751         
00752 
00753 #elif defined(__sun) && !defined(RECOVERABLE_CRITICAL_SECTION)
00754 // Sun uses the Solaris style semaphore implemenation (sema_init(), sema_post())
00755 #include <synch.h>
00756 #include <errno.h>
00757 typedef sema_t sharedsem_t;
00758 
00759 class dbGlobalCriticalSection { 
00760     sharedsem_t* sem;
00761   public:
00762     void enter() { 
00763         int rc;
00764         while ((rc = sema_wait(sem)) < 0 && errno == EINTR);
00765         assert(rc == 0);
00766     }
00767     void leave() { 
00768         int rc = sema_post(sem);
00769         assert(rc == 0);
00770     }
00771     bool open(char const*, sharedsem_t* shr) { 
00772         sem = shr;
00773         return true;
00774     }
00775     bool create(char const*, sharedsem_t* shr) { 
00776         sem = shr;
00777         return sema_init(shr, 1, USYNC_PROCESS, NULL) == 0;
00778     }
00779     void close() {}
00780     void erase() {
00781         sema_destroy(sem);
00782     }
00783 };
00784 
00785 #elif defined(USE_POSIX_SEMAPHORES) && !defined(RECOVERABLE_CRITICAL_SECTION)
00786 // Everyone else uses the POSIX style semaphores (sem_wait(), sem_post(), etc) if defined
00787 typedef sem_t sharedsem_t;
00788 
00789 class dbGlobalCriticalSection { 
00790     sharedsem_t* sem;
00791 
00792   public:
00793     void enter() { 
00794         int rc = sem_wait(sem);
00795         assert(rc == 0);
00796     }
00797     void leave() { 
00798         int rc = sem_post(sem);
00799         assert(rc == 0);
00800     }
00801     bool open(char const* name, sharedsem_t* shr) { 
00802         sem = shr;
00803         return true;
00804     }
00805 
00806     bool create(char const* name, sharedsem_t* shr) {   
00807         sem = shr;
00808         return sem_init(sem, 1, 1) == 0;
00809     }
00810 
00811     void close() {}
00812     void erase() { 
00813         sem_destroy(sem);
00814     }
00815 };
00816 
00817 #else
00818 
00819 #define USE_LOCAL_CS_IMPL
00820 
00821 // Lastly, use the local implementation
00822 typedef long sharedsem_t;
00823 
00824 class dbGlobalCriticalSection { 
00825     int          semid;
00826     sharedsem_t* count;
00827 
00828   public:
00829     void enter(); 
00830     void leave();
00831     bool open(char const* name, sharedsem_t* shr);
00832     bool create(char const* name, sharedsem_t* shr);
00833     void close() {}
00834     void erase();
00835 };
00836 #endif //dbGLobalCriticalSection switch
00837 
00838 END_FASTDB_NAMESPACE
00839 
00840 #endif //__SYNC_UNIX_H__

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