Index: pjproject/trunk/pjlib/src/pj/os_core_unix.c
===================================================================
--- pjproject/trunk/pjlib/src/pj/os_core_unix.c	(revision 2216)
+++ pjproject/trunk/pjlib/src/pj/os_core_unix.c	(revision 2217)
@@ -89,5 +89,5 @@
 struct pj_sem_t
 {
-    sem_t		sem;
+    sem_t	       *sem;
     char		obj_name[PJ_MAX_OBJ_NAME];
 };
@@ -1471,6 +1471,40 @@
     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. */
@@ -1509,5 +1543,5 @@
 			      pj_thread_this()->obj_name));
 
-    result = sem_wait( &sem->sem );
+    result = sem_wait( sem->sem );
     
     if (result == 0) {
@@ -1540,5 +1574,5 @@
     PJ_ASSERT_RETURN(sem, PJ_EINVAL);
 
-    result = sem_trywait( &sem->sem );
+    result = sem_trywait( sem->sem );
     
     if (result == 0) {
@@ -1565,5 +1599,5 @@
     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)
@@ -1590,5 +1624,9 @@
     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)
Index: pjproject/trunk/pjlib/src/pjlib-test/mutex.c
===================================================================
--- pjproject/trunk/pjlib/src/pjlib-test/mutex.c	(revision 2216)
+++ pjproject/trunk/pjlib/src/pjlib-test/mutex.c	(revision 2217)
@@ -149,4 +149,57 @@
 }
 
+#if PJ_HAS_SEMAPHORE
+static int semaphore_test(pj_pool_t *pool)
+{
+    pj_sem_t *sem;
+    pj_status_t status;
+
+    PJ_LOG(3,("", "...testing semaphore"));
+
+    status = pj_sem_create(pool, NULL, 0, 1, &sem);
+    if (status != PJ_SUCCESS) {
+	app_perror("...error: pj_sem_create()", status);
+	return -151;
+    }
+
+    status = pj_sem_post(sem);
+    if (status != PJ_SUCCESS) {
+	app_perror("...error: pj_sem_post()", status);
+	pj_sem_destroy(sem);
+	return -153;
+    }
+
+    status = pj_sem_trywait(sem);
+    if (status != PJ_SUCCESS) {
+	app_perror("...error: pj_sem_trywait()", status);
+	pj_sem_destroy(sem);
+	return -156;
+    }
+
+    status = pj_sem_post(sem);
+    if (status != PJ_SUCCESS) {
+	app_perror("...error: pj_sem_post()", status);
+	pj_sem_destroy(sem);
+	return -159;
+    }
+
+    status = pj_sem_wait(sem);
+    if (status != PJ_SUCCESS) {
+	app_perror("...error: pj_sem_wait()", status);
+	pj_sem_destroy(sem);
+	return -161;
+    }
+
+    status = pj_sem_destroy(sem);
+    if (status != PJ_SUCCESS) {
+	app_perror("...error: pj_sem_destroy()", status);
+	return -163;
+    }
+
+    return 0;
+}
+#endif	/* PJ_HAS_SEMAPHORE */
+
+
 int mutex_test(void)
 {
@@ -164,4 +217,10 @@
 	return rc;
 
+#if PJ_HAS_SEMAPHORE
+    rc = semaphore_test(pool);
+    if (rc != 0)
+	return rc;
+#endif
+
     pj_pool_release(pool);
 
