src/CMakeLists.txt | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/shm/hashtable.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/svsem.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/svsem.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/svsem_util.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/CMakeLists.txt
@@ -16,7 +16,7 @@ ./socket/shm_mod_socket.cpp ./time_util.cpp ./psem.cpp ./svsem_util.cpp ./svsem.cpp ./bus_error.cpp ./futex_sem.cpp ./net/net_conn_pool.cpp @@ -62,7 +62,7 @@ ./time_util.h ./futex_sem.h ./bus_error.h ./svsem_util.h ./svsem.h ./logger_factory.h ./queue/linked_lock_free_queue.h ./queue/array_lock_free_queue2.h src/shm/hashtable.cpp
@@ -1,7 +1,7 @@ #include "usg_common.h" #include "hashtable.h" #include "mm.h" #include "sem_util.h" #include "svsem.h" #include "logger_factory.h" #include <set> #include <functional> @@ -30,9 +30,9 @@ { memset(hashtable, 0, sizeof(hashtable_t)); hashtable->mutex = SemUtil::get(IPC_PRIVATE, 1); hashtable->wlock = SemUtil::get(IPC_PRIVATE, 1); hashtable->cond = SemUtil::get(IPC_PRIVATE, 1); hashtable->mutex = svsem_get(IPC_PRIVATE, 1); hashtable->wlock = svsem_get(IPC_PRIVATE, 1); hashtable->cond = svsem_get(IPC_PRIVATE, 1); hashtable->readcnt = 0; FILE * semfile = fopen("./sem.txt", "w+"); @@ -44,9 +44,9 @@ } void hashtable_destroy(hashtable_t *hashtable) { SemUtil::remove( hashtable->mutex); SemUtil::remove( hashtable->wlock); SemUtil::remove( hashtable->cond); svsem_remove( hashtable->mutex); svsem_remove( hashtable->wlock); svsem_remove( hashtable->cond); } @@ -111,13 +111,13 @@ void *oldvalue; int rv; if( (rv = SemUtil::dec(hashtable->wlock)) != 0) { if( (rv = svsem_wait(hashtable->wlock)) != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_remove\n"); } tailq_header_t *my_tailq_head = hashtable->array[code] ; if ( my_tailq_head == NULL) { SemUtil::inc(hashtable->wlock); svsem_post(hashtable->wlock); return NULL; } else @@ -132,12 +132,12 @@ /* mm_free the item as we don't need it anymore. */ mm_free(item); SemUtil::inc(hashtable->wlock); svsem_post(hashtable->wlock); return oldvalue; } } } if((rv = SemUtil::inc(hashtable->wlock)) != 0) { if((rv = svsem_post(hashtable->wlock)) != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_remove\n"); } @@ -153,7 +153,7 @@ { tailq_entry_t *item; int rv; rv = SemUtil::dec(hashtable->wlock); rv = svsem_wait(hashtable->wlock); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_removeall\n"); } @@ -172,7 +172,7 @@ mm_free(my_tailq_head); hashtable->array[i] = NULL; } rv = SemUtil::inc(hashtable->wlock); rv = svsem_post(hashtable->wlock); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_removeall\n"); } @@ -208,12 +208,12 @@ } void *hashtable_get(hashtable_t *hashtable, int key) { LoggerFactory::getLogger()->debug( "==========hashtable_get before 1"); LoggerFactory::getLogger()->debug( "==========hashtable_get before 1"); int rv; rv = SemUtil::dec(hashtable->mutex); rv = svsem_wait(hashtable->mutex); LoggerFactory::getLogger()->debug( "==========hashtable_get before 2"); LoggerFactory::getLogger()->debug( "==========hashtable_get before 2"); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_get 1"); @@ -221,12 +221,14 @@ hashtable->readcnt++; if (hashtable->readcnt == 1) { //获取读写锁 rv = SemUtil::dec(hashtable->wlock); LoggerFactory::getLogger()->debug( "==========hashtable_get before 3"); rv = svsem_wait(hashtable->wlock); LoggerFactory::getLogger()->debug( "==========hashtable_get before 4"); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_get 2"); } } rv = SemUtil::inc(hashtable->mutex); rv = svsem_post(hashtable->mutex); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_get 3"); } @@ -236,70 +238,78 @@ // ================== rv = SemUtil::dec(hashtable->mutex); rv = svsem_wait(hashtable->mutex); LoggerFactory::getLogger()->debug( "==========hashtable_get before 5"); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_get 4"); } hashtable->readcnt--; if(hashtable->readcnt == 0) { //释放读写锁 rv = SemUtil::inc(hashtable->wlock); rv = svsem_post(hashtable->wlock); LoggerFactory::getLogger()->debug( "==========hashtable_get before 6"); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_get 5"); } //通知写 rv = SemUtil::set(hashtable->cond, 1); rv = svsem_set(hashtable->cond, 1); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_get 6"); } } rv = SemUtil::inc(hashtable->mutex); rv = svsem_post(hashtable->mutex); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_get 7"); } LoggerFactory::getLogger()->debug( "==========hashtable_get after"); LoggerFactory::getLogger()->debug( "==========hashtable_get after"); return res; } void hashtable_put(hashtable_t *hashtable, int key, void *value) { int rv; LoggerFactory::getLogger()->debug( "==========hashtable_put before"); rv = SemUtil::dec(hashtable->mutex); LoggerFactory::getLogger()->debug( "==========hashtable_put before 1"); rv = svsem_wait(hashtable->mutex); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_put\n"); } LoggerFactory::getLogger()->debug( "==========hashtable_put before 2"); // 设置读优先级高 while (hashtable->readcnt > 0) { rv = SemUtil::set(hashtable->cond, 0); rv = svsem_set(hashtable->cond, 0); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_put\n"); } rv = SemUtil::inc(hashtable->mutex); rv = svsem_post(hashtable->mutex); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_put\n"); } //等待写通知 rv = SemUtil::dec(hashtable->cond); LoggerFactory::getLogger()->debug( "==========hashtable_put before 3"); rv = svsem_wait(hashtable->cond); LoggerFactory::getLogger()->debug( "==========hashtable_put before 4"); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_put\n"); } rv = SemUtil::dec(hashtable->mutex); rv = svsem_wait(hashtable->mutex); LoggerFactory::getLogger()->debug( "==========hashtable_put before 5"); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_put\n"); } } rv = SemUtil::inc(hashtable->mutex); rv = svsem_post(hashtable->mutex); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_put\n"); } //获取读写锁 rv = SemUtil::dec(hashtable->wlock); rv = svsem_wait(hashtable->wlock); LoggerFactory::getLogger()->debug( "==========hashtable_put before 6"); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_put\n"); } @@ -307,7 +317,7 @@ _hashtable_put(hashtable, key, value); //释放读写锁 rv = SemUtil::inc(hashtable->wlock); rv = svsem_post(hashtable->wlock); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_put\n"); } @@ -335,21 +345,26 @@ void hashtable_foreach(hashtable_t *hashtable, std::function<void(int, void *)> cb) { int rv; rv = SemUtil::dec(hashtable->mutex); LoggerFactory::getLogger()->debug("===hashtable_foreach before 1\n"); rv = svsem_wait(hashtable->mutex); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_foreach\n"); LoggerFactory::getLogger()->error(rv, "hashtable_foreach"); } hashtable->readcnt++; if (hashtable->readcnt == 1) { //获取读写锁 rv = SemUtil::dec(hashtable->wlock); rv = svsem_wait(hashtable->wlock); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_foreach\n"); LoggerFactory::getLogger()->error(rv, "hashtable_foreach"); } } rv = SemUtil::inc(hashtable->mutex); rv = svsem_post(hashtable->mutex); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_foreach\n"); LoggerFactory::getLogger()->error(rv, "hashtable_foreach"); } // ================== @@ -358,26 +373,26 @@ // ================== rv = SemUtil::dec(hashtable->mutex); rv = svsem_wait(hashtable->mutex); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_foreach\n"); LoggerFactory::getLogger()->error(rv, "hashtable_foreach"); } hashtable->readcnt--; if(hashtable->readcnt == 0) { //释放读写锁 rv = SemUtil::inc(hashtable->wlock); rv = svsem_post(hashtable->wlock); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_foreach\n"); LoggerFactory::getLogger()->error(rv, "hashtable_foreach"); } //通知写 rv = SemUtil::set(hashtable->cond, 1); rv = svsem_set(hashtable->cond, 1); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_foreach\n"); LoggerFactory::getLogger()->error(rv, "hashtable_foreach"); } } rv = SemUtil::inc(hashtable->mutex); rv = svsem_post(hashtable->mutex); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_foreach\n"); LoggerFactory::getLogger()->error(rv, "hashtable_foreach"); } } @@ -404,7 +419,7 @@ int hashtable_alloc_key(hashtable_t *hashtable) { int rv; int key = START_KEY; rv = SemUtil::dec(hashtable->wlock); rv = svsem_wait(hashtable->wlock); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_alloc_key\n"); } @@ -415,7 +430,7 @@ // 占用key _hashtable_put(hashtable, key, (void *)1); rv = SemUtil::inc(hashtable->wlock); rv = svsem_post(hashtable->wlock); if(rv != 0) { LoggerFactory::getLogger()->error(rv, "hashtable_alloc_key\n"); } src/svsem.cpp
File was renamed from src/svsem_util.cpp @@ -1,12 +1,12 @@ #include "svsem_util.h" #include "svsem.h" int SvsemUtil::get(key_t key, int nsems, unsigned short * arr_val) { // printf("==================SvsemUtil::get===============================\n"); int svsem_get(key_t key, unsigned int value) { // printf("==================svsem_get===============================\n"); int semid, perms; perms = S_IRUSR | S_IWUSR; semid = semget(key, nsems, IPC_CREAT | IPC_EXCL | perms); semid = semget(key, 1, IPC_CREAT | IPC_EXCL | perms); if (semid != -1) { /* Successfully created the semaphore */ union semun arg; @@ -14,8 +14,8 @@ //logger.info("%ld: created semaphore\n", (long)getpid()); arg.array = arr_val; /* So initialize it to arr_val */ if (semctl(semid, 0, SETALL, arg) == -1) arg.val = 0; /* So initialize it to 0 */ if (semctl(semid, 0, SETVAL, arg) == -1) err_exit(errno, "semctl 1"); //logger.info("%ld: initialized semaphore\n", (long)getpid()); @@ -23,7 +23,7 @@ so other processes can see we've initialized the set. */ sop.sem_num = 0; /* Operate on semaphore 0 */ sop.sem_op = arr_val[0]; sop.sem_op = value; sop.sem_flg = 0; if (semop(semid, &sop, 1) == -1) err_exit(errno, "semop"); @@ -40,7 +40,7 @@ union semun arg; struct semid_ds ds; semid = semget(key, nsems, perms); /* So just get ID */ semid = semget(key, 1, perms); /* So just get ID */ if (semid == -1) err_exit(errno, "semget 2"); @@ -69,51 +69,68 @@ set to EINTR if operation was interrupted by a signal handler */ /* Reserve semaphore - decrement it by 1 */ int SvsemUtil::dec(int semId) { int svsem_wait(int semid) { struct sembuf sops; sops.sem_num = 0; sops.sem_op = -1; sops.sem_flg = 0; while (semop(semId, &sops, 1) == -1) while (semop(semid, &sops, 1) == -1) if (errno != EINTR) { // err_msg(errno, "SvsemUtil::dec"); // err_msg(errno, "svsem_dec"); return errno; } return 0; } int SvsemUtil::dec_nowait(int semId) { int svsem_trywait(int semid) { struct sembuf sops; sops.sem_num = 0; sops.sem_op = -1; sops.sem_flg = IPC_NOWAIT | SEM_UNDO; sops.sem_flg = IPC_NOWAIT | 0; while (semop(semId, &sops, 1) == -1) while (semop(semid, &sops, 1) == -1) if (errno != EINTR) { // err_msg(errno, "SvsemUtil::dec_nowait"); // err_msg(errno, "svsem_dec_nowait"); return errno; } return 0; } int SvsemUtil::dec_timeout(const int semId, const struct timespec *timeout) { int svsem_timedwait(const int semid, const struct timespec *timeout) { struct sembuf sops; sops.sem_num = 0; sops.sem_op = -1; sops.sem_flg = 0; while (semtimedop(semId, &sops, 1, timeout) == -1) while (semtimedop(semid, &sops, 1, timeout) == -1) if (errno != EINTR) { // err_msg(errno, "SvsemUtil::dec_timeout"); // err_msg(errno, "svsem_psem_timedwait"); return errno; } return 0; } /* Release semaphore - increment it by 1 */ int svsem_post(int semid) { struct sembuf sops; sops.sem_num = 0; sops.sem_op = 1; sops.sem_flg = 0; int rv = semop(semid, &sops, 1); if (rv == -1) { // err_msg(errno, "svsem_inc"); return errno; } return 0; } @@ -123,17 +140,17 @@ * currently equals 0. If it does, the operation completes immediately; otherwise, * semop() blocks until the semaphore value becomes 0. */ int SvsemUtil::zero(int semId) { // logger.debug("%d: SvsemUtil::dec\n", semId); int svsem_zero(int semid) { // logger.debug("%d: svsem_dec\n", semid); struct sembuf sops; sops.sem_num = 0; sops.sem_op = 0; sops.sem_flg = 0; while (semop(semId, &sops, 1) == -1) while (semop(semid, &sops, 1) == -1) if (errno != EINTR) { // err_msg(errno, "SvsemUtil::zero"); // err_msg(errno, "svsem_zero"); return errno; } @@ -141,32 +158,32 @@ } int SvsemUtil::zero_nowait(int semId) { int svsem_zero_nowait(int semid) { struct sembuf sops; sops.sem_num = 0; sops.sem_op = 0; sops.sem_flg = IPC_NOWAIT; while (semop(semId, &sops, 1) == -1) while (semop(semid, &sops, 1) == -1) if (errno != EINTR) { // err_msg(errno, "SvsemUtil::zero_nowait"); // err_msg(errno, "svsem_zero_nowait"); return errno; } return 0; } int SvsemUtil::zero_timeout(const int semId, const struct timespec *timeout) { int svsem_zero_timeout(const int semid, const struct timespec *timeout) { struct sembuf sops; sops.sem_num = 0; sops.sem_op = 0; sops.sem_flg = 0; while (semtimedop(semId, &sops, 1, timeout) == -1) while (semtimedop(semid, &sops, 1, timeout) == -1) if (errno != EINTR) { // err_msg(errno, "SvsemUtil::zero_timeout"); // err_msg(errno, "svsem_zero_timeout"); return errno; } @@ -174,37 +191,30 @@ } /* Release semaphore - increment it by 1 */ int SvsemUtil::inc(int semId) { struct sembuf sops; sops.sem_num = 0; sops.sem_op = 1; sops.sem_flg = 0; int rv = semop(semId, &sops, 1); if (rv == -1) { // err_msg(errno, "SvsemUtil::inc"); return errno; } return 0; } int SvsemUtil::set(int semId, int val) { int svsem_set(int semid, int val) { union semun arg; arg.val = val; if (semctl(semId, 0, SETVAL, arg) == -1) { err_msg(errno, "SvsemUtil::set"); if (semctl(semid, 0, SETVAL, arg) == -1) { err_msg(errno, "svsem_set"); return errno; } return 0; } void svsem_remove(int semid) { union semun dummy; if (semctl(semid, 0, IPC_RMID, dummy) == -1) err_msg(errno, "svsem_remove"); } int SvsemUtil::cond_wait(int semId ){ int svsem_cond_wait(int semid ){ struct sembuf sops[2]; @@ -218,9 +228,9 @@ sops[1].sem_op = -1; sops[1].sem_flg = 0; while (semop(semId, sops, 2) == -1) while (semop(semid, sops, 2) == -1) if (errno != EINTR) { // err_msg(errno, "SvsemUtil::dec"); // err_msg(errno, "Svsvsem_dec"); return errno; } @@ -230,7 +240,7 @@ return 0; } int SvsemUtil::cond_signal(int semId ){ int svsem_cond_signal(int semid ){ struct sembuf sops; // 通知等待cond的进程 @@ -238,16 +248,11 @@ sops.sem_op = 1; sops.sem_flg = 0; int rv = semop(semId, &sops, 1); int rv = semop(semid, &sops, 1); if (rv == -1) { // err_msg(errno, "SvsemUtil::inc"); // err_msg(errno, "Svsvsem_inc"); return errno; } return 0; } void SvsemUtil::remove(int semid) { union semun dummy; if (semctl(semid, 0, IPC_RMID, dummy) == -1) err_msg(errno, "SvsemUtil::remove"); } src/svsem.h
New file @@ -0,0 +1,47 @@ #ifndef _SVSEM_UTIL_H #define _SVSEM_UTIL_H #include "usg_common.h" int svsem_get(key_t key, unsigned int value) ; /* Reserve semaphore (blocking), return 0 on success, or -1 with 'errno' set to EINTR if operation was interrupted by a signal handler */ /* Reserve semaphore - decrement it by 1 */ int svsem_wait(int semid) ; int svsem_trywait(int semid) ; int svsem_timedwait(const int semid, const struct timespec *timeout) ; /* Release semaphore - increment it by 1 */ int svsem_post(int semid) ; int svsem_cond_wait(int semid ) ; int svsem_cond_signal(int semid ) ; /** * If sem_op equals 0, the value of the semaphore is checked to see whether it * currently equals 0. If it does, the operation completes immediately; otherwise, * semop() blocks until the semaphore value becomes 0. */ int svsem_zero(int semid) ; int svsem_zero_nowait(int semid) ; int svsem_zero_timeout(const int semid, const struct timespec *timeout) ; int svsem_set(int semid, int val) ; void svsem_remove(int semid) ; #endif src/svsem_util.h
File was deleted