diff options
author | Benny Prijono <bennylp@teluu.com> | 2008-08-15 14:53:18 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2008-08-15 14:53:18 +0000 |
commit | 2f24a0b188d55837e7c11fcbef53153702560699 (patch) | |
tree | 94db942df28cfcb4c37846be58ddc67c84df2dc6 /pjlib/src/pj/os_core_unix.c | |
parent | dda962837e8e9d4c28c0d5bb7f30ffebc79f4db8 (diff) |
Ticket #595: Broken semaphore implementation on MacOS X (thanks Viktor Krikun for the report)
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2217 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib/src/pj/os_core_unix.c')
-rw-r--r-- | pjlib/src/pj/os_core_unix.c | 50 |
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; |