| | |
| | | #include "bh_api.h" |
| | | #include "svsem.h" |
| | | #include "msg_mgr.h" |
| | | |
| | | int svsem_get(key_t key, unsigned int value) { |
| | | // printf("==================svsem_get===============================\n"); |
| | | int semid, perms; |
| | | |
| | | perms = S_IRUSR | S_IWUSR; |
| | | perms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; |
| | | |
| | | semid = semget(key, 2, IPC_CREAT | IPC_EXCL | perms); |
| | | |
| | | if (semid != -1) { /* Successfully created the semaphore */ |
| | | union semun arg; |
| | | struct sembuf sop; |
| | | |
| | | //logger.info("%ld: created semaphore\n", (long)getpid()); |
| | | |
| | | arg.val = 0; /* So initialize it to 0 */ |
| | | if (semctl(semid, 0, SETVAL, arg) == -1) |
| | |
| | | arg.val = 1; |
| | | if (semctl(semid, 1, SETVAL, arg) == -1) |
| | | err_exit(errno, "semctl 2"); |
| | | //logger.info("%ld: initialized semaphore\n", (long)getpid()); |
| | | |
| | | |
| | | /* Perform a "no-op" semaphore operation - changes sem_otime |
| | | so other processes can see we've initialized the set. */ |
| | | |
| | | sop.sem_num = 0; /* Operate on semaphore 0 */ |
| | | sop.sem_op = value; |
| | | sop.sem_flg = 0; |
| | | sop.sem_flg = SEM_UNDO; |
| | | if (semop(semid, &sop, 1) == -1) |
| | | err_exit(errno, "semop"); |
| | | //logger.info("%ld: completed dummy semop()\n", (long)getpid()); |
| | | |
| | | } else { /* We didn't create the semaphore set */ |
| | | |
| | |
| | | if (semid == -1) |
| | | err_exit(errno, "semget 2"); |
| | | |
| | | // logger.info("%ld: got semaphore key\n", (long)getpid()); |
| | | /* Wait until another process has called semop() */ |
| | | |
| | | arg.buf = &ds; |
| | | for (j = 0; j < MAX_TRIES; j++) { |
| | | //logger.info("Try %d\n", j); |
| | | if (semctl(semid, 0, IPC_STAT, arg) == -1) |
| | | err_exit(errno, "semctl 2"); |
| | | |
| | |
| | | |
| | | sops.sem_num = 0; |
| | | sops.sem_op = -1; |
| | | sops.sem_flg = 0; |
| | | sops.sem_flg = SEM_UNDO; |
| | | |
| | | while (semop(semid, &sops, 1) == -1) |
| | | if (errno != EINTR) { |
| | | // err_msg(errno, "svsem_dec"); |
| | | err_msg(errno, "svsem_dec"); |
| | | |
| | | return -1; |
| | | } |
| | | |
| | | #if defined(MSG_HANDLER) |
| | | Msg_info msg_obj; |
| | | |
| | | msg_obj.key = inter_key_get(); |
| | | msg_obj.id = semid; |
| | | msg_obj.act = SEM_GET; |
| | | msg_distrib(SEM_TYPE_ID, &msg_obj); |
| | | #endif |
| | | |
| | | return 0; |
| | | } |
| | |
| | | |
| | | sops.sem_num = 0; |
| | | sops.sem_op = -1; |
| | | sops.sem_flg = IPC_NOWAIT | 0; |
| | | sops.sem_flg = IPC_NOWAIT | SEM_UNDO; |
| | | |
| | | #if defined(MSG_HANDLER) |
| | | Msg_info msg_obj; |
| | | |
| | | msg_obj.key = inter_key_get(); |
| | | msg_obj.id = semid; |
| | | msg_obj.act = SEM_GET; |
| | | msg_distrib(SEM_TYPE_ID, &msg_obj); |
| | | #endif |
| | | |
| | | return semop(semid, &sops, 1) ; |
| | | } |
| | | |
| | | int svsem_timedwait(const int semid, const struct timespec *timeout) { |
| | | int svsem_timedwait(int semid, struct timespec *timeout) { |
| | | struct sembuf sops; |
| | | |
| | | sops.sem_num = 0; |
| | | sops.sem_op = -1; |
| | | sops.sem_flg = 0; |
| | | sops.sem_flg = SEM_UNDO; |
| | | |
| | | while (semtimedop(semid, &sops, 1, timeout) == -1) |
| | | if (errno != EINTR) { |
| | |
| | | return -1; |
| | | } |
| | | |
| | | #if defined(MSG_HANDLER) |
| | | Msg_info msg_obj; |
| | | |
| | | msg_obj.key = inter_key_get(); |
| | | msg_obj.id = semid; |
| | | msg_obj.act = SEM_GET; |
| | | msg_distrib(SEM_TYPE_ID, &msg_obj); |
| | | #endif |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | int svsem_uni_wait(int semid) { |
| | | struct timespec res; |
| | | |
| | | res.tv_sec = SEM_WT_TIMEOUT; |
| | | res.tv_nsec = 0; |
| | | |
| | | while(1) { |
| | | if(svsem_timedwait(semid, &res) != 0) { |
| | | |
| | | if(svsem_post(semid) != 0) { |
| | | err_msg(errno, "_inc"); |
| | | } |
| | | |
| | | } else { |
| | | |
| | | break; |
| | | } |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | /* Release semaphore - increment it by 1 */ |
| | | int svsem_post(int semid) { |
| | |
| | | |
| | | sops.sem_num = 0; |
| | | sops.sem_op = 1; |
| | | sops.sem_flg = 0; |
| | | sops.sem_flg = SEM_UNDO; |
| | | |
| | | int rv = semop(semid, &sops, 1); |
| | | if (rv == -1) { |
| | | // err_msg(errno, "svsem_inc"); |
| | | return -1; |
| | | } |
| | | |
| | | #if defined(MSG_HANDLER) |
| | | Msg_info msg_obj; |
| | | |
| | | msg_obj.key = inter_key_get(); |
| | | msg_obj.id = semid; |
| | | msg_obj.act = SEM_POST; |
| | | msg_distrib(SEM_TYPE_ID, &msg_obj); |
| | | #endif |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | int svsem_cond_wait(int semid ){ |
| | | |
| | |
| | | //释放mutex |
| | | sops[0].sem_num = 0; |
| | | sops[0].sem_op = 1; |
| | | sops[0].sem_flg = 0; |
| | | sops[0].sem_flg = SEM_UNDO; |
| | | |
| | | // 等待cond |
| | | sops[1].sem_num = 1; |
| | | sops[1].sem_op = 0; |
| | | sops[1].sem_flg = 0; |
| | | sops[1].sem_flg = SEM_UNDO; |
| | | |
| | | while (semop(semid, sops, 2) == -1) |
| | | if (errno != EINTR) { |
| | |
| | | //重新获取mutex |
| | | sops[0].sem_num = 0; |
| | | sops[0].sem_op = -1; |
| | | sops[0].sem_flg = 0; |
| | | sops[0].sem_flg = SEM_UNDO; |
| | | |
| | | while (semop(semid, sops, 1) == -1) |
| | | if (errno != EINTR) { |
| | | // err_msg(errno, "Svsvsem_dec"); |
| | | return -1; |
| | | } |
| | | |
| | | #if defined(MSG_HANDLER) |
| | | Msg_info msg_obj; |
| | | |
| | | msg_obj.key = inter_key_get(); |
| | | msg_obj.id = semid; |
| | | msg_obj.act = SEM_GET; |
| | | msg_distrib(SEM_TYPE_ID, &msg_obj); |
| | | #endif |
| | | |
| | | return 0; |
| | | } |
| | |
| | | |
| | | sops.sem_num = 0; |
| | | sops.sem_op = 0; |
| | | sops.sem_flg = 0; |
| | | sops.sem_flg = SEM_UNDO; |
| | | |
| | | while (semop(semid, &sops, 1) == -1) |
| | | if (errno != EINTR) { |
| | | // err_msg(errno, "svsem_zero"); |
| | | return -1; |
| | | } |
| | | |
| | | #if defined(MSG_HANDLER) |
| | | Msg_info msg_obj; |
| | | |
| | | msg_obj.key = inter_key_get(); |
| | | msg_obj.id = semid; |
| | | msg_obj.act = SEM_RESET; |
| | | msg_distrib(SEM_TYPE_ID, &msg_obj); |
| | | #endif |
| | | |
| | | return 0; |
| | | } |
| | |
| | | |
| | | sops.sem_num = 0; |
| | | sops.sem_op = 0; |
| | | sops.sem_flg = IPC_NOWAIT; |
| | | sops.sem_flg = IPC_NOWAIT | SEM_UNDO; |
| | | |
| | | while (semop(semid, &sops, 1) == -1) |
| | | if (errno != EINTR) { |
| | |
| | | return -1; |
| | | } |
| | | |
| | | #if defined(MSG_HANDLER) |
| | | Msg_info msg_obj; |
| | | msg_obj.key = inter_key_get(); |
| | | msg_obj.id = semid; |
| | | msg_obj.act = SEM_RESET; |
| | | msg_distrib(SEM_TYPE_ID, &msg_obj); |
| | | #endif |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | int svsem_zero_timeout(const int semid, const struct timespec *timeout) { |
| | | int svsem_zero_timeout(int semid, struct timespec *timeout) { |
| | | struct sembuf sops; |
| | | |
| | | sops.sem_num = 0; |
| | | sops.sem_op = 0; |
| | | sops.sem_flg = 0; |
| | | sops.sem_flg = SEM_UNDO; |
| | | |
| | | while (semtimedop(semid, &sops, 1, timeout) == -1) |
| | | if (errno != EINTR) { |
| | |
| | | return -1; |
| | | } |
| | | |
| | | #if defined(MSG_HANDLER) |
| | | Msg_info msg_obj; |
| | | msg_obj.key = inter_key_get(); |
| | | msg_obj.id = semid; |
| | | msg_obj.act = SEM_RESET; |
| | | msg_distrib(SEM_TYPE_ID, &msg_obj); |
| | | #endif |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | int svsem_set(int semid, int val) { |
| | | union semun arg; |
| | |
| | | return semctl(semid, 0, SETVAL, arg); |
| | | } |
| | | |
| | | |
| | | void svsem_remove(int semid) { |
| | | union semun dummy; |
| | | |
| | | if (semctl(semid, 0, IPC_RMID, dummy) == -1) |
| | | err_msg(errno, "svsem_remove"); |
| | | |
| | | #if defined(MSG_HANDLER) |
| | | Msg_info msg_obj; |
| | | msg_obj.key = inter_key_get(); |
| | | msg_obj.id = semid; |
| | | msg_obj.act = SEM_RM; |
| | | msg_distrib(SEM_TYPE_ID, &msg_obj); |
| | | #endif |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |