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/ |