summaryrefslogtreecommitdiff
path: root/pjlib/src/pj/os_core_unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'pjlib/src/pj/os_core_unix.c')
-rw-r--r--pjlib/src/pj/os_core_unix.c50
1 files changed, 44 insertions, 6 deletions
diff --git a/pjlib/src/pj/os_core_unix.c b/pjlib/src/pj/os_core_unix.c
index 006f2a0b..9543737f 100644
--- a/pjlib/src/pj/os_core_unix.c
+++ b/pjlib/src/pj/os_core_unix.c
@@ -88,7 +88,7 @@ struct pj_mutex_t
#if defined(PJ_HAS_SEMAPHORE) && PJ_HAS_SEMAPHORE != 0
struct pj_sem_t
{
- sem_t sem;
+ sem_t *sem;
char obj_name[PJ_MAX_OBJ_NAME];
};
#endif /* PJ_HAS_SEMAPHORE */
@@ -1470,8 +1470,42 @@ PJ_DEF(pj_status_t) pj_sem_create( pj_pool_t *pool,
sem = PJ_POOL_ALLOC_T(pool, pj_sem_t);
PJ_ASSERT_RETURN(sem, PJ_ENOMEM);
- if (sem_init( &sem->sem, 0, initial) != 0)
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+ /* MacOS X doesn't support anonymous semaphore */
+ {
+ char sem_name[PJ_GUID_MAX_LENGTH+1];
+ pj_str_t nam;
+
+ /* We should use SEM_NAME_LEN, but this doesn't seem to be
+ * declared anywhere? The value here is just from trial and error
+ * to get the longest name supported.
+ */
+# define MAX_SEM_NAME_LEN 23
+
+ /* Create a unique name for the semaphore. */
+ if (PJ_GUID_STRING_LENGTH <= MAX_SEM_NAME_LEN) {
+ nam.ptr = sem_name;
+ pj_generate_unique_string(&nam);
+ sem_name[nam.slen] = '\0';
+ } else {
+ pj_create_random_string(sem_name, MAX_SEM_NAME_LEN);
+ sem_name[MAX_SEM_NAME_LEN] = '\0';
+ }
+
+ /* Create semaphore */
+ sem->sem = sem_open(sem_name, O_CREAT|O_EXCL, S_IRUSR|S_IWUSR,
+ initial);
+ if (sem->sem == SEM_FAILED)
+ return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
+
+ /* And immediately release the name as we don't need it */
+ sem_unlink(sem_name);
+ }
+#else
+ sem->sem = PJ_POOL_ALLOC_T(pool, sem_t);
+ if (sem_init( sem->sem, 0, initial) != 0)
return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
+#endif
/* Set name. */
if (!name) {
@@ -1508,7 +1542,7 @@ PJ_DEF(pj_status_t) pj_sem_wait(pj_sem_t *sem)
PJ_LOG(6, (sem->obj_name, "Semaphore: thread %s is waiting",
pj_thread_this()->obj_name));
- result = sem_wait( &sem->sem );
+ result = sem_wait( sem->sem );
if (result == 0) {
PJ_LOG(6, (sem->obj_name, "Semaphore acquired by thread %s",
@@ -1539,7 +1573,7 @@ PJ_DEF(pj_status_t) pj_sem_trywait(pj_sem_t *sem)
PJ_CHECK_STACK();
PJ_ASSERT_RETURN(sem, PJ_EINVAL);
- result = sem_trywait( &sem->sem );
+ result = sem_trywait( sem->sem );
if (result == 0) {
PJ_LOG(6, (sem->obj_name, "Semaphore acquired by thread %s",
@@ -1564,7 +1598,7 @@ PJ_DEF(pj_status_t) pj_sem_post(pj_sem_t *sem)
int result;
PJ_LOG(6, (sem->obj_name, "Semaphore released by thread %s",
pj_thread_this()->obj_name));
- result = sem_post( &sem->sem );
+ result = sem_post( sem->sem );
if (result == 0)
return PJ_SUCCESS;
@@ -1589,7 +1623,11 @@ PJ_DEF(pj_status_t) pj_sem_destroy(pj_sem_t *sem)
PJ_LOG(6, (sem->obj_name, "Semaphore destroyed by thread %s",
pj_thread_this()->obj_name));
- result = sem_destroy( &sem->sem );
+#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0
+ result = sem_close( sem->sem );
+#else
+ result = sem_destroy( sem->sem );
+#endif
if (result == 0)
return PJ_SUCCESS;