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

📄 sync.h

📁 实现内存数据库的源代码
💻 H
📖 第 1 页 / 共 2 页
字号:

class dbThread { 
  public:
    void create(void (thread_proc* f)(void*), void* arg) { f(arg); }
    void join() {}
    void detach() {}
    static int numberOfProcessors() { return 1; }
};

class dbLocalSemaphore { 
    int count;
  public:
    void wait(dbMutex&) { 
	assert (count > 0);
	count -= 1;
    }
    void signal(unsigned inc = 1) {
	count += inc;
    }
    void open(unsigned initValue = 0) {
	count = initValue;
    }
    void close() {}
};

class dbLocalEvent { 
    bool signaled;
  public:
    void wait(dbMutex&) { 
	assert(signaled);
    }
    void signal() {
	signaled = true;
    }
    void reset() {
	signaled = false;
    }
    void open(bool initValue = false) {
	signaled = initValue;
    }
    void close() {}
};

template<class T>
class dbThreadContext { 
    T* value;
  public:
    T* get() { 
	return value;
    }
    void set(T* value) { 
	this->value = value;
    }
    dbThreadContext() { value = NULL; }
};


class dbProcessId { 
    int       pid;
  public:
    bool operator != (dbProcessId const& other) const { 
	return pid != other.pid;
    }
    
    void clear() { 
	pid = 0;
    }

    static dbProcessId getCurrent() {
	dbProcessId curr;
	curr.pid = getpid();
	return curr;
    }
};

#endif

#define INFINITE (~0U)

#ifdef USE_POSIX_API

class dbInitializationMutex { 
    sem_t* sem;
  public: 
    enum initializationStatus { 
	InitializationError, 
	AlreadyInitialized,
	NotYetInitialized
    };
    initializationStatus initialize(char const* name) { 
	initializationStatus status;
	char* tmp = NULL;
	if (*name != '/') { 
	    tmp = new char[strlen(name)+2];
	    strcpy(tmp+1, name);
	    *tmp = '/';
	    name = tmp;
	}
	while (true) {
	    sem = sem_open(name, 0);
	    if (sem == NULL) { 
		if (errno == ENOENT) {
		    sem = sem_open(name, O_CREAT|O_EXCL, 0777, 0);
		    if (sem != NULL) { 
			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;
	    }
	}
	delete[] tmp;
	return status;
    }

    void done() { 
	sem_post(sem);
    }
    bool close() {
	sem_close(sem);
	return false;
    }
    void erase() { 
	close();
    }
};


class dbSemaphore { 
  protected:
    sem_t* sem;
  public:
    void wait() { 
	int rc = sem_wait(sem);
	assert(rc == 0);
    }

    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 + tv.tv_usec / 1000) / 1000000; 
	abs_ts.tv_nsec = (msec + tv.tv_usec / 1000) % 1000000 * 1000;
	int rc = sem_timedwait(sem, &abs_ts);
	if (rc < 0) { 
	    assert(errno == ETIMEDOUT);
	    return false;
	}
	return true;
#else 
	int rc = sem_wait(sem);
	assert(rc == 0);
	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) {
	char* tmp = NULL;
	if (*name != '/') { 
	    tmp = new char[strlen(name)+2];
	    strcpy(tmp+1, name);
	    *tmp = '/';
	    name = tmp;
	}
	sem = sem_open(name, O_CREAT, 0777, initValue);
	delete[] tmp;
	return sem != NULL; 
    }
    void close() {
	sem_close(sem);
    }
    void erase() { 
	close();
    }
};

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);
    }
};

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;
	}
	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(ptr, DOALIGN(sizeof(T), 4096));
	}
	if (fd > 0) { 
	    ::close(fd);
	}
    }
    void erase() { 
	close();
	unlink(name);	
	name = NULL;
    }  

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

#else // USE_POSIX_API

extern char const* keyFileDir; // default value: "/tmp/" 

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();
};

template<class T>
class dbSharedObject { 
    T*  ptr;
    int shm;
  public:

    bool open(char* name) { 
	char* fileName = name;
	if (*name != '/') { 
	    fileName = new char[strlen(name)+strlen(keyFileDir)+1];
	    sprintf(fileName, "%s%s", keyFileDir, name);
	}
	int fd = ::open(fileName, O_RDWR|O_CREAT, 0777);
	if (fd < 0) { 
	    if (fileName != name) { 
		delete[] fileName;
	    }
	    return false;
	} 
	::close(fd);
	int key = ftok(fileName, '0');
	if (fileName != name) { 
	    delete[] fileName;
	}
	if (key < 0) { 
	    return false;
	}
	shm = shmget(key, DOALIGN(sizeof(T), 4096), IPC_CREAT|0777);
	if (shm < 0) { 
	    return false;
	}
	ptr = (T*)shmat(shm, NULL, 0);
	return (ptr != (T*)-1);
    }

    T* get() { return ptr; }

    void close() { 
	shmdt((char*)ptr);
    }
    void erase() { 
	close();
	shmctl(shm, IPC_RMID, NULL);
    }  
};

#endif

#if defined(__QNX__)

typedef pthread_mutext_t sharedsem_t;

class dbGlobalCriticalSection { 
    pthread_mutexattr_t attr;
    sharedsem_t* sem;
  public:
    void enter() {
	int rc = pthread_mutex_lock(sem);
	assert(rc == 0);
    }
    void leave() { 
	int rc = pthread_mutex_unlock(sem);
	assert(rc == 0);
    }
    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);
	pthread_mutex_init(sem, &attr);
	return true;
    }
    void close() {}
    void erase() {
	pthread_mutex_destroy(sem);
    }
};


#elif defined(__osf__)

#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)

#include <synch.h>
#include <errno.h>
typedef sema_t sharedsem_t;

class dbGlobalCriticalSection { 
    sharedsem_t* sem;
  public:
    void enter() { 
	int rc;
	while ((rc = sema_wait(sem)) < 0 && errno == EINTR);
	assert(rc == 0);
    }
    void leave() { 
	int rc = sema_post(sem);
	assert(rc == 0);
    }
    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_API)

typedef sem_t sharedsem_t;

class dbGlobalCriticalSection { 
    sharedsem_t* sem;

  public:
    void enter() { 
	int rc = sem_wait(sem);
	assert(rc == 0);
    }
    void leave() { 
	int rc = sem_post(sem);
	assert(rc == 0);
    }
    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

typedef long sharedsem_t;

class dbGlobalCriticalSection { 
    int          semid;
    sharedsem_t* count;

  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

#endif

class FASTDB_DLL_ENTRY dbCriticalSection { 
  private:
    dbMutex& mutex;
  public:
    dbCriticalSection(dbMutex& guard) : mutex(guard) {
	mutex.lock();
    }
    ~dbCriticalSection() { 
	mutex.unlock();
    }
};
	
#define SMALL_BUF_SIZE 1024

class FASTDB_DLL_ENTRY dbSmallBuffer { 
  protected:
    char* buf;
    char  smallBuf[SMALL_BUF_SIZE];

  public:
    dbSmallBuffer(size_t size) { 
	if (size > SMALL_BUF_SIZE) { 
	    buf = new char[size];
	} else { 
	    buf = smallBuf;
	}
    }

    operator char*() { return buf; }
    char* base() { return buf; }

    ~dbSmallBuffer() { 
	if (buf != smallBuf) { 
	    delete[] buf;
	}
    }
};

#endif


⌨️ 快捷键说明

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