| ringbuffer_helper.c | ringbuffer_helper.c | |||
|---|---|---|---|---|
| skipping to change at line 24 | skipping to change at line 24 | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU Lesser General Public License for more details. | * GNU Lesser General Public License for more details. | |||
| * | * | |||
| * You should have received a copy of the GNU Lesser General Public License | * You should have received a copy of the GNU Lesser General Public License | |||
| * along with libqb. If not, see <http://www.gnu.org/licenses/>. | * along with libqb. If not, see <http://www.gnu.org/licenses/>. | |||
| */ | */ | |||
| #include "ringbuffer_int.h" | #include "ringbuffer_int.h" | |||
| #include <qb/qbdefs.h> | #include <qb/qbdefs.h> | |||
| static int32_t my_posix_sem_timedwait(qb_ringbuffer_t * rb, int32_t ms_time | static int32_t | |||
| out) | my_posix_sem_timedwait(qb_ringbuffer_t * rb, int32_t ms_timeout) | |||
| { | { | |||
| struct timespec ts_timeout; | struct timespec ts_timeout; | |||
| int32_t res; | int32_t res; | |||
| if (ms_timeout > 0) { | if (ms_timeout > 0) { | |||
| qb_util_timespec_from_epoch_get(&ts_timeout); | qb_util_timespec_from_epoch_get(&ts_timeout); | |||
| qb_timespec_add_ms(&ts_timeout, ms_timeout); | qb_timespec_add_ms(&ts_timeout, ms_timeout); | |||
| } | } | |||
| sem_wait_again: | sem_wait_again: | |||
| skipping to change at line 55 | skipping to change at line 56 | |||
| goto sem_wait_again; | goto sem_wait_again; | |||
| break; | break; | |||
| case EAGAIN: | case EAGAIN: | |||
| res = -ETIMEDOUT; | res = -ETIMEDOUT; | |||
| break; | break; | |||
| case ETIMEDOUT: | case ETIMEDOUT: | |||
| res = -errno; | res = -errno; | |||
| break; | break; | |||
| default: | default: | |||
| res = -errno; | res = -errno; | |||
| qb_util_log(LOG_ERR, | qb_util_perror(LOG_ERR, "error waiting for semaphore | |||
| "error waiting for semaphore : %s", | "); | |||
| strerror(errno)); | ||||
| break; | break; | |||
| } | } | |||
| } | } | |||
| return res; | return res; | |||
| } | } | |||
| static int32_t my_sysv_sem_timedwait(qb_ringbuffer_t * rb, int32_t ms_timeo | static int32_t | |||
| ut) | my_posix_sem_post(qb_ringbuffer_t * rb) | |||
| { | ||||
| if (sem_post(&rb->shared_hdr->posix_sem) < 0) { | ||||
| return -errno; | ||||
| } else { | ||||
| return 0; | ||||
| } | ||||
| } | ||||
| static ssize_t | ||||
| my_posix_getvalue_fn(struct qb_ringbuffer_s *rb) | ||||
| { | ||||
| int val; | ||||
| if (sem_getvalue(&rb->shared_hdr->posix_sem, &val) < 0) { | ||||
| return -errno; | ||||
| } else { | ||||
| return val; | ||||
| } | ||||
| } | ||||
| static int32_t | ||||
| my_posix_sem_destroy(qb_ringbuffer_t * rb) | ||||
| { | ||||
| if (sem_destroy(&rb->shared_hdr->posix_sem) == -1) { | ||||
| return -errno; | ||||
| } else { | ||||
| return 0; | ||||
| } | ||||
| } | ||||
| static int32_t | ||||
| my_posix_sem_create(struct qb_ringbuffer_s *rb, uint32_t flags) | ||||
| { | ||||
| int32_t pshared = 0; | ||||
| if (flags & QB_RB_FLAG_SHARED_PROCESS) { | ||||
| if ((flags & QB_RB_FLAG_CREATE) == 0) { | ||||
| return 0; | ||||
| } | ||||
| pshared = 1; | ||||
| } | ||||
| if (sem_init(&rb->shared_hdr->posix_sem, pshared, 0) == -1) { | ||||
| return -errno; | ||||
| } else { | ||||
| return 0; | ||||
| } | ||||
| } | ||||
| #ifndef HAVE_POSIX_SHARED_SEMAPHORE | ||||
| static int32_t | ||||
| my_sysv_sem_timedwait(qb_ringbuffer_t * rb, int32_t ms_timeout) | ||||
| { | { | |||
| struct sembuf sops[1]; | struct sembuf sops[1]; | |||
| int32_t res = 0; | int32_t res = 0; | |||
| #ifndef QB_FREEBSD_GE_8 | #ifndef QB_FREEBSD_GE_8 | |||
| struct timespec ts_timeout; | struct timespec ts_timeout; | |||
| struct timespec *ts_pt; | struct timespec *ts_pt; | |||
| if (ms_timeout >= 0) { | if (ms_timeout >= 0) { | |||
| /* | /* | |||
| * Note: sem_timedwait takes an absolute time where as semti medop | * Note: sem_timedwait takes an absolute time where as semti medop | |||
| skipping to change at line 99 | skipping to change at line 148 | |||
| sops[0].sem_num = 0; | sops[0].sem_num = 0; | |||
| sops[0].sem_op = -1; | sops[0].sem_op = -1; | |||
| #ifdef QB_FREEBSD_GE_8 | #ifdef QB_FREEBSD_GE_8 | |||
| sops[0].sem_flg = IPC_NOWAIT; | sops[0].sem_flg = IPC_NOWAIT; | |||
| #else | #else | |||
| sops[0].sem_flg = 0; | sops[0].sem_flg = 0; | |||
| #endif /* bsd */ | #endif /* bsd */ | |||
| semop_again: | semop_again: | |||
| #ifdef QB_FREEBSD_GE_8 | #ifdef QB_FREEBSD_GE_8 | |||
| if (semop(rb->sem_id, sops, 1) == -1) { | if (semop(rb->sem_id, sops, 1) == -1) | |||
| #else | #else | |||
| if (semtimedop(rb->sem_id, sops, 1, ts_pt) == -1) { | if (semtimedop(rb->sem_id, sops, 1, ts_pt) == -1) | |||
| #endif | #endif | |||
| { | ||||
| if (errno == EINTR) { | if (errno == EINTR) { | |||
| goto semop_again; | goto semop_again; | |||
| } else if (errno == EAGAIN) { | } else if (errno == EAGAIN) { | |||
| /* make consistent with sem_timedwait */ | /* make consistent with sem_timedwait */ | |||
| res = -ETIMEDOUT; | res = -ETIMEDOUT; | |||
| } else { | } else { | |||
| res = -errno; | res = -errno; | |||
| qb_util_log(LOG_ERR, | qb_util_perror(LOG_ERR, "error waiting for semaphore | |||
| "error waiting for semaphore : %s", | "); | |||
| strerror(errno)); | ||||
| } | } | |||
| return res; | return res; | |||
| } | } | |||
| return 0; | return 0; | |||
| } | } | |||
| static int32_t my_posix_sem_post(qb_ringbuffer_t * rb) | static int32_t | |||
| { | my_sysv_sem_post(qb_ringbuffer_t * rb) | |||
| if (sem_post(&rb->shared_hdr->posix_sem) < 0) { | ||||
| return -errno; | ||||
| } else { | ||||
| return 0; | ||||
| } | ||||
| } | ||||
| static ssize_t my_posix_getvalue_fn(struct qb_ringbuffer_s *rb) | ||||
| { | ||||
| int val; | ||||
| if (sem_getvalue(&rb->shared_hdr->posix_sem, &val) < 0) { | ||||
| return -errno; | ||||
| } else { | ||||
| return val; | ||||
| } | ||||
| } | ||||
| static int32_t my_sysv_sem_post(qb_ringbuffer_t * rb) | ||||
| { | { | |||
| struct sembuf sops[1]; | struct sembuf sops[1]; | |||
| if ((rb->flags & QB_RB_FLAG_SHARED_PROCESS) == 0) { | if ((rb->flags & QB_RB_FLAG_SHARED_PROCESS) == 0) { | |||
| return 0; | return 0; | |||
| } | } | |||
| sops[0].sem_num = 0; | sops[0].sem_num = 0; | |||
| sops[0].sem_op = 1; | sops[0].sem_op = 1; | |||
| sops[0].sem_flg = 0; | sops[0].sem_flg = 0; | |||
| semop_again: | semop_again: | |||
| if (semop(rb->sem_id, sops, 1) == -1) { | if (semop(rb->sem_id, sops, 1) == -1) { | |||
| if (errno == EINTR) { | if (errno == EINTR) { | |||
| goto semop_again; | goto semop_again; | |||
| } else { | } else { | |||
| qb_util_log(LOG_ERR, | qb_util_perror(LOG_ERR, | |||
| "could not increment semaphore : %s", | "could not increment semaphore"); | |||
| strerror(errno)); | ||||
| } | } | |||
| return -errno; | return -errno; | |||
| } | } | |||
| return 0; | return 0; | |||
| } | } | |||
| static ssize_t my_sysv_getvalue_fn(struct qb_ringbuffer_s *rb) | static ssize_t | |||
| my_sysv_getvalue_fn(struct qb_ringbuffer_s *rb) | ||||
| { | { | |||
| ssize_t res = semctl(rb->sem_id, 0, GETVAL, 0); | ssize_t res = semctl(rb->sem_id, 0, GETVAL, 0); | |||
| if (res == -1) { | if (res == -1) { | |||
| return -errno; | return -errno; | |||
| } | } | |||
| return res; | return res; | |||
| } | } | |||
| static int32_t my_posix_sem_destroy(qb_ringbuffer_t * rb) | static int32_t | |||
| { | my_sysv_sem_destroy(qb_ringbuffer_t * rb) | |||
| if (sem_destroy(&rb->shared_hdr->posix_sem) == -1) { | ||||
| return -errno; | ||||
| } else { | ||||
| return 0; | ||||
| } | ||||
| } | ||||
| static int32_t my_sysv_sem_destroy(qb_ringbuffer_t * rb) | ||||
| { | { | |||
| if (semctl(rb->sem_id, 0, IPC_RMID, 0) == -1) { | if (semctl(rb->sem_id, 0, IPC_RMID, 0) == -1) { | |||
| return -errno; | return -errno; | |||
| } else { | } else { | |||
| return 0; | return 0; | |||
| } | } | |||
| } | } | |||
| static int32_t my_posix_sem_create(struct qb_ringbuffer_s *rb, uint32_t fla | static int32_t | |||
| gs) | my_sysv_sem_create(qb_ringbuffer_t * rb, uint32_t flags) | |||
| { | ||||
| int32_t pshared = 0; | ||||
| if (flags & QB_RB_FLAG_SHARED_PROCESS) { | ||||
| if ((flags & QB_RB_FLAG_CREATE) == 0) { | ||||
| return 0; | ||||
| } | ||||
| pshared = 1; | ||||
| } | ||||
| if (sem_init(&rb->shared_hdr->posix_sem, pshared, 0) == -1) { | ||||
| return -errno; | ||||
| } else { | ||||
| return 0; | ||||
| } | ||||
| } | ||||
| static int32_t my_sysv_sem_create(qb_ringbuffer_t * rb, uint32_t flags) | ||||
| { | { | |||
| union semun options; | union semun options; | |||
| int32_t res; | int32_t res; | |||
| key_t sem_key; | key_t sem_key; | |||
| sem_key = ftok(rb->shared_hdr->hdr_path, (rb->shared_hdr->size + 1)) ; | sem_key = ftok(rb->shared_hdr->hdr_path, (rb->shared_hdr->size + 1)) ; | |||
| if (sem_key == -1) { | if (sem_key == -1) { | |||
| res = -errno; | res = -errno; | |||
| qb_util_log(LOG_ERR, "couldn't get a sem id %s", | qb_util_perror(LOG_ERR, "couldn't get a sem id"); | |||
| strerror(errno)); | ||||
| return res; | return res; | |||
| } | } | |||
| if (flags & QB_RB_FLAG_CREATE) { | if (flags & QB_RB_FLAG_CREATE) { | |||
| rb->sem_id = semget(sem_key, 1, IPC_CREAT | IPC_EXCL | 0600) ; | rb->sem_id = semget(sem_key, 1, IPC_CREAT | IPC_EXCL | 0600) ; | |||
| if (rb->sem_id == -1) { | if (rb->sem_id == -1) { | |||
| res = -errno; | res = -errno; | |||
| qb_util_log(LOG_ERR, "couldn't create a semaphore %s | qb_util_perror(LOG_ERR, "couldn't create a semaphore | |||
| ", | "); | |||
| strerror(errno)); | ||||
| return res; | return res; | |||
| } | } | |||
| options.val = 0; | options.val = 0; | |||
| res = semctl(rb->sem_id, 0, SETVAL, options); | res = semctl(rb->sem_id, 0, SETVAL, options); | |||
| } else { | } else { | |||
| rb->sem_id = semget(sem_key, 0, 0600); | rb->sem_id = semget(sem_key, 0, 0600); | |||
| if (rb->sem_id == -1) { | if (rb->sem_id == -1) { | |||
| res = -errno; | res = -errno; | |||
| qb_util_log(LOG_ERR, "couldn't get a sem id %s", | qb_util_perror(LOG_ERR, "couldn't get a sem id"); | |||
| strerror(errno)); | ||||
| return res; | return res; | |||
| } | } | |||
| res = 0; | res = 0; | |||
| } | } | |||
| qb_util_log(LOG_INFO, "sem key:%d, id:%d, value:%d", | qb_util_log(LOG_DEBUG, "sem key:%d, id:%d, value:%d", | |||
| (int)sem_key, rb->sem_id, semctl(rb->sem_id, 0, GETVAL, 0)); | (int)sem_key, rb->sem_id, semctl(rb->sem_id, 0, GETVAL, 0)); | |||
| return res; | return res; | |||
| } | } | |||
| #endif /* NOT HAVE_POSIX_SHARED_SEMAPHORE */ | ||||
| int32_t qb_rb_sem_create(struct qb_ringbuffer_s * rb, uint32_t flags) | int32_t | |||
| qb_rb_sem_create(struct qb_ringbuffer_s * rb, uint32_t flags) | ||||
| { | { | |||
| int32_t can_use_shared_posix = QB_FALSE; | #ifndef HAVE_POSIX_SHARED_SEMAPHORE | |||
| #ifdef HAVE_POSIX_SHARED_SEMAPHORE | if (rb->flags & QB_RB_FLAG_SHARED_PROCESS) { | |||
| can_use_shared_posix = QB_TRUE; | ||||
| #endif /* HAVE_POSIX_SHARED_SEMAPHORE */ | ||||
| if (!can_use_shared_posix && (rb->flags & QB_RB_FLAG_SHARED_PROCESS) | ||||
| ) { | ||||
| rb->sem_timedwait_fn = my_sysv_sem_timedwait; | rb->sem_timedwait_fn = my_sysv_sem_timedwait; | |||
| rb->sem_post_fn = my_sysv_sem_post; | rb->sem_post_fn = my_sysv_sem_post; | |||
| rb->sem_getvalue_fn = my_sysv_getvalue_fn; | rb->sem_getvalue_fn = my_sysv_getvalue_fn; | |||
| rb->sem_destroy_fn = my_sysv_sem_destroy; | rb->sem_destroy_fn = my_sysv_sem_destroy; | |||
| return my_sysv_sem_create(rb, flags); | return my_sysv_sem_create(rb, flags); | |||
| } else { | } else | |||
| #endif /* NOT HAVE_POSIX_SHARED_SEMAPHORE */ | ||||
| { | ||||
| rb->sem_timedwait_fn = my_posix_sem_timedwait; | rb->sem_timedwait_fn = my_posix_sem_timedwait; | |||
| rb->sem_post_fn = my_posix_sem_post; | rb->sem_post_fn = my_posix_sem_post; | |||
| rb->sem_getvalue_fn = my_posix_getvalue_fn; | rb->sem_getvalue_fn = my_posix_getvalue_fn; | |||
| rb->sem_destroy_fn = my_posix_sem_destroy; | rb->sem_destroy_fn = my_posix_sem_destroy; | |||
| return my_posix_sem_create(rb, flags); | return my_posix_sem_create(rb, flags); | |||
| } | } | |||
| } | } | |||
| End of changes. 20 change blocks. | ||||
| 80 lines changed or deleted | 83 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||