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/