⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sync_unix.h

📁 最新版本!fastdb是高效的内存数据库系统
💻 H
📖 第 1 页 / 共 2 页
字号:
                    if (sem != SEM_FAILED) { 
                        status = NotYetInitialized;
                        break;
                    } else if (errno != EEXIST) { 
                        status = InitializationError;
                        break;
                    }
                } else { 
                    status = InitializationError;
                    break;
                }
            } else { 
                status = (sem_wait(sem) == 0 && sem_post(sem) == 0) 
                    ? AlreadyInitialized : InitializationError;
                break;
            }
        }
        return status;
    }

    void done() { 
        sem_post(sem);
    }
    bool close() {
        sem_close(sem);
        return true;
    }
    void erase() {
        sem_unlink(name);
        delete[] name;
    }
};

class dbSemaphore { 
  protected:
    sem_t* sem;
    char*  name;
  public:
    void wait() { 
#ifdef NDEBUG
        sem_wait(sem);
#else
        int rc = sem_wait(sem);
        assert(rc == 0);
#endif
    }

    bool wait(unsigned msec) { 
#ifdef POSIX_1003_1d
        struct timespec abs_ts;
        struct timeval  cur_tv;
        clock_gettime(CLOCK_REALTIME, &cur_tv);
        abs_ts.tv_sec = cur_tv.tv_sec + (msec + cur_tv.tv_usec / 1000) / 1000000; 
        abs_ts.tv_nsec = (msec + cur_tv.tv_usec / 1000) % 1000000 * 1000;
        int rc = sem_timedwait(sem, &abs_ts);
        if (rc < 0) { 
            assert(errno == ETIMEDOUT);
            return false;
        }
        return true;
#else 
#ifdef NDEBUG
        sem_wait(sem);
#else
        int rc = sem_wait(sem);
        assert(rc == 0);
#endif
        return true;
#endif  
    }

    void signal(unsigned inc = 1) {
        while (inc-- > 0) { 
            sem_post(sem);
        }
    }
    void reset() { 
        while (sem_trywait(sem) == 0);
    }    
    bool open(char const* name, unsigned initValue = 0) {
        this->name = new char[strlen(name)+2];
        if (*name != '/') { 
            strcpy(this->name+1, name);
            *this->name = '/';
        } else { 
            strcpy(this->name, name);
        }
        sem = sem_open(this->name, O_CREAT, 0777, initValue);
        return sem != NULL; 
    }
    void close() {
        if (sem != NULL) { 
            sem_close(sem);
            sem = NULL;
        }
    }
    void erase() { 
        close();
        sem_unlink(name);
        delete[] name;
    }
};

class dbEvent : public dbSemaphore { 
  public:
    void wait() { 
        dbSemaphore::wait();
        sem_post(sem);
    }
    bool wait(unsigned msec) { 
        if (dbSemaphore::wait(msec)) { 
            sem_post(sem);
            return true;
        }
        return false;
    }
    void signal() {
        while (sem_trywait(sem) == 0);
        sem_post(sem);
    }
    void reset() {
        while (sem_trywait(sem) == 0);
    }
    bool open(char const* name, bool signaled = false) {
        return dbSemaphore::open(name, (int)signaled);
    }
};
#else // USE_POSIX_SEMAPHORES

class FASTDB_DLL_ENTRY dbWatchDog { 
    bool open(char const* name, int flags);
  public:
    bool watch();
    void close(); 
    bool open(char const* name);
    bool create(char const* name);
    int id;
};

// Define local implemenation of InitializationMutex in sync.cpp
class dbInitializationMutex { 
    int semid;
  public: 
    enum initializationStatus { 
        InitializationError, 
        AlreadyInitialized,
        NotYetInitialized
    };
    initializationStatus initialize(char const* name);
    void done(); 
    bool close();
    void erase();
};


class dbSemaphore { 
    int s;
  public:
    bool wait(unsigned msec = INFINITE);
    void signal(unsigned inc = 1);
    bool open(char const* name, unsigned initValue = 0);
    void reset();
    void close();
    void erase();
};

class dbEvent { 
    int e;
  public:
    bool wait(unsigned msec = INFINITE);
    void signal();
    void reset();
    bool open(char const* name, bool signaled = false);
    void close();
    void erase();
};
#endif // USE_POSIX_SEMAPHORES


// Define dbSharedObject and dbSharedMemory
#if defined(USE_POSIX_MMAP) && USE_POSIX_MMAP

// For POSIX dbSharedObject, we use mmap()
template<class T>
class dbSharedObject { 
    char* name;
    T*  ptr;
    int fd;
  public:

    dbSharedObject() { 
        name = NULL;
        ptr = NULL;
        fd = -1;
    }

    bool open(char* fileName) { 
        delete[] name;
        name = new char[strlen(fileName) + 1];
        strcpy(name, fileName);
        fd = ::open(fileName, O_RDWR|O_CREAT, 0777);
        if (fd < 0) { 
            return false;
        }
        if (ftruncate(fd, sizeof(T)) < 0) {
            ::close(fd);
            return false;
        }
        ptr = (T*)mmap(NULL,
                       DOALIGN(sizeof(T), 4096),
                       PROT_READ|PROT_WRITE,
                       MAP_SHARED,
                       fd,
                       0);
        if (ptr == MAP_FAILED) { 
            ptr = NULL;
            ::close(fd);
            return false;
        }
        return true;
    }

    T* get() { return ptr; }

    void close() { 
        if (ptr != NULL) { 
            munmap((char*)ptr, DOALIGN(sizeof(T), 4096));
        }
        if (fd > 0) { 
            ::close(fd);
        }
    }
    void erase() {
        close();
        unlink(name);   
    }  

    ~dbSharedObject() { 
        delete[] name;
    }
};

#else // USE_POSIX_MMAP

// Non POSIX, internal implementations of SharedMemory and SharedObject
extern char const* keyFileDir; // default value: "/tmp/" 
class dbSharedMemory { 
  protected:
    char*  ptr;
    int    shm;

  public:
    bool  open(char const* name, size_t size); 
    void  close();
    void  erase(); 
    char* get_base() { 
        return ptr;
    }
};

template<class T>
class dbSharedObject : public dbSharedMemory { 
  public:
    bool open(char* name) { 
        return dbSharedMemory::open(name, sizeof(T));
    }
    T* get() { return (T*)ptr; }
};

#endif

//////////////////////////////////////////////////////////////////////////
// Define dBGlobalCriticalSection for various platforms

// QNX uses a pthread based mutex for its implementation
//     Use only if pthread support is also enabled, else we'll use the default case
#if defined(__QNX__) && !defined(NO_PTHREADS)
typedef pthread_mutex_t sharedsem_t;

class dbGlobalCriticalSection { 
    pthread_mutexattr_t attr;
    sharedsem_t* sem;
  public:
    void enter() {
#ifdef NDEBUG
        pthread_mutex_lock(sem);
#else
        int rc = pthread_mutex_lock(sem);
        assert(rc == 0);
#endif
    }
    void leave() { 
#ifdef NDEBUG
        pthread_mutex_unlock(sem);
#else
        int rc = pthread_mutex_unlock(sem);
        assert(rc == 0);
#endif
    }
    bool open(char const*, sharedsem_t* shr) { 
        sem = shr;
        return true;
    }
    bool create(char const*, sharedsem_t* shr) { 
        sem = shr;
        pthread_mutexattr_init(&attr);
        pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
        pthread_mutexattr_setrecursive(&attr, PTHREAD_RECURSIVE_ENABLE);
#ifdef VXWORKS
	memset(&sem, '\0', sizeof(*sem));
#endif // VXWORKS
        pthread_mutex_init(sem, &attr);
        return true;
    }
    void close() {}
    void erase() {
        pthread_mutex_destroy(sem);
    }
};


#elif defined(__osf__) && !defined(RECOVERABLE_CRITICAL_SECTION)
// OSF uses "shared memory semaphores", located within a region mapped with mmap().
#include <errno.h>
typedef msemaphore sharedsem_t;

class dbGlobalCriticalSection { 
    sharedsem_t* sem;
  public:
    void enter() { 
        int rc;
        while ((rc = msem_lock(sem, 0)) < 0 && errno == EINTR);
        assert(rc == 0);
    }
    void leave() { 
        int rc = msem_unlock(sem, 0);
        assert(rc == 0);        
    }
    bool open(char const*, sharedsem_t* shr) { 
        sem = shr;
        return true;
    }
    bool create(char const*, sharedsem_t* shr) { 
        sem = shr;
        msem_init(shr, MSEM_UNLOCKED);
        return true;
    }
    void close() {}
    void erase() {
        msem_remove(sem);
    }
};
        

#elif defined(__sun) && !defined(RECOVERABLE_CRITICAL_SECTION)
// Sun uses the Solaris style semaphore implemenation (sema_init(), sema_post())
#include <synch.h>
#include <errno.h>
typedef sema_t sharedsem_t;

class dbGlobalCriticalSection { 
    sharedsem_t* sem;
  public:
    void enter() { 
#ifdef NDEBUG
        while (sema_wait(sem) < 0 && errno == EINTR);
#else
        int rc;
        while ((rc = sema_wait(sem)) < 0 && errno == EINTR);
        assert(rc == 0);
#endif
    }
    void leave() { 
#ifdef NDEBUG
        sema_post(sem);
#else
        int rc = sema_post(sem);
        assert(rc == 0);
#endif
    }
    bool open(char const*, sharedsem_t* shr) { 
        sem = shr;
        return true;
    }
    bool create(char const*, sharedsem_t* shr) { 
        sem = shr;
        return sema_init(shr, 1, USYNC_PROCESS, NULL) == 0;
    }
    void close() {}
    void erase() {
        sema_destroy(sem);
    }
};

#elif defined(USE_POSIX_SEMAPHORES) && !defined(RECOVERABLE_CRITICAL_SECTION)
// Everyone else uses the POSIX style semaphores (sem_wait(), sem_post(), etc) if defined
typedef sem_t sharedsem_t;

class dbGlobalCriticalSection { 
    sharedsem_t* sem;

  public:
    void enter() { 
#ifdef NDEBUG
        sem_wait(sem);
#else
        int rc = sem_wait(sem);
        assert(rc == 0);
#endif
    }
    void leave() { 
#ifdef NDEBUG
        sem_post(sem);
#else
        int rc = sem_post(sem);
        assert(rc == 0);
#endif
    }
    bool open(char const* name, sharedsem_t* shr) { 
        sem = shr;
        return true;
    }

    bool create(char const* name, sharedsem_t* shr) {   
        sem = shr;
        return sem_init(sem, 1, 1) == 0;
    }

    void close() {}
    void erase() { 
        sem_destroy(sem);
    }
};

#else

#define USE_INTERNAL_CS_IMPL

#define GLOBAL_CS_DEBUG 1

// Lastly, use the local implementation
typedef int sharedsem_t;

class dbGlobalCriticalSection { 
    int          semid;
    sharedsem_t* count;
#if GLOBAL_CS_DEBUG
    pthread_t    owner;
#endif

  public:
    void enter(); 
    void leave();
    bool open(char const* name, sharedsem_t* shr);
    bool create(char const* name, sharedsem_t* shr);
    void close() {}
    void erase();
};
#endif //dbGLobalCriticalSection switch

END_FASTDB_NAMESPACE

#endif //__SYNC_UNIX_H__

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -