Changeset 2217


Ignore:
Timestamp:
Aug 15, 2008 2:53:18 PM (11 years ago)
Author:
bennylp
Message:

Ticket #595: Broken semaphore implementation on MacOS X (thanks Viktor Krikun for the report)

Location:
pjproject/trunk/pjlib/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib/src/pj/os_core_unix.c

    r2159 r2217  
    8989struct pj_sem_t 
    9090{ 
    91     sem_t               sem; 
     91    sem_t              *sem; 
    9292    char                obj_name[PJ_MAX_OBJ_NAME]; 
    9393}; 
     
    14711471    PJ_ASSERT_RETURN(sem, PJ_ENOMEM); 
    14721472 
    1473     if (sem_init( &sem->sem, 0, initial) != 0)  
     1473#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 
     1474    /* MacOS X doesn't support anonymous semaphore */ 
     1475    { 
     1476        char sem_name[PJ_GUID_MAX_LENGTH+1]; 
     1477        pj_str_t nam; 
     1478 
     1479        /* We should use SEM_NAME_LEN, but this doesn't seem to be  
     1480         * declared anywhere? The value here is just from trial and error 
     1481         * to get the longest name supported. 
     1482         */ 
     1483#       define MAX_SEM_NAME_LEN 23 
     1484 
     1485        /* Create a unique name for the semaphore. */ 
     1486        if (PJ_GUID_STRING_LENGTH <= MAX_SEM_NAME_LEN) { 
     1487            nam.ptr = sem_name; 
     1488            pj_generate_unique_string(&nam); 
     1489            sem_name[nam.slen] = '\0'; 
     1490        } else { 
     1491            pj_create_random_string(sem_name, MAX_SEM_NAME_LEN); 
     1492            sem_name[MAX_SEM_NAME_LEN] = '\0'; 
     1493        } 
     1494 
     1495        /* Create semaphore */ 
     1496        sem->sem = sem_open(sem_name, O_CREAT|O_EXCL, S_IRUSR|S_IWUSR,  
     1497                            initial); 
     1498        if (sem->sem == SEM_FAILED) 
     1499            return PJ_RETURN_OS_ERROR(pj_get_native_os_error()); 
     1500 
     1501        /* And immediately release the name as we don't need it */ 
     1502        sem_unlink(sem_name); 
     1503    } 
     1504#else 
     1505    sem->sem = PJ_POOL_ALLOC_T(pool, sem_t); 
     1506    if (sem_init( sem->sem, 0, initial) != 0)  
    14741507        return PJ_RETURN_OS_ERROR(pj_get_native_os_error()); 
     1508#endif 
    14751509     
    14761510    /* Set name. */ 
     
    15091543                              pj_thread_this()->obj_name)); 
    15101544 
    1511     result = sem_wait( &sem->sem ); 
     1545    result = sem_wait( sem->sem ); 
    15121546     
    15131547    if (result == 0) { 
     
    15401574    PJ_ASSERT_RETURN(sem, PJ_EINVAL); 
    15411575 
    1542     result = sem_trywait( &sem->sem ); 
     1576    result = sem_trywait( sem->sem ); 
    15431577     
    15441578    if (result == 0) { 
     
    15651599    PJ_LOG(6, (sem->obj_name, "Semaphore released by thread %s", 
    15661600                              pj_thread_this()->obj_name)); 
    1567     result = sem_post( &sem->sem ); 
     1601    result = sem_post( sem->sem ); 
    15681602 
    15691603    if (result == 0) 
     
    15901624    PJ_LOG(6, (sem->obj_name, "Semaphore destroyed by thread %s", 
    15911625                              pj_thread_this()->obj_name)); 
    1592     result = sem_destroy( &sem->sem ); 
     1626#if defined(PJ_DARWINOS) && PJ_DARWINOS!=0 
     1627    result = sem_close( sem->sem ); 
     1628#else 
     1629    result = sem_destroy( sem->sem ); 
     1630#endif 
    15931631 
    15941632    if (result == 0) 
  • pjproject/trunk/pjlib/src/pjlib-test/mutex.c

    r2039 r2217  
    149149} 
    150150 
     151#if PJ_HAS_SEMAPHORE 
     152static int semaphore_test(pj_pool_t *pool) 
     153{ 
     154    pj_sem_t *sem; 
     155    pj_status_t status; 
     156 
     157    PJ_LOG(3,("", "...testing semaphore")); 
     158 
     159    status = pj_sem_create(pool, NULL, 0, 1, &sem); 
     160    if (status != PJ_SUCCESS) { 
     161        app_perror("...error: pj_sem_create()", status); 
     162        return -151; 
     163    } 
     164 
     165    status = pj_sem_post(sem); 
     166    if (status != PJ_SUCCESS) { 
     167        app_perror("...error: pj_sem_post()", status); 
     168        pj_sem_destroy(sem); 
     169        return -153; 
     170    } 
     171 
     172    status = pj_sem_trywait(sem); 
     173    if (status != PJ_SUCCESS) { 
     174        app_perror("...error: pj_sem_trywait()", status); 
     175        pj_sem_destroy(sem); 
     176        return -156; 
     177    } 
     178 
     179    status = pj_sem_post(sem); 
     180    if (status != PJ_SUCCESS) { 
     181        app_perror("...error: pj_sem_post()", status); 
     182        pj_sem_destroy(sem); 
     183        return -159; 
     184    } 
     185 
     186    status = pj_sem_wait(sem); 
     187    if (status != PJ_SUCCESS) { 
     188        app_perror("...error: pj_sem_wait()", status); 
     189        pj_sem_destroy(sem); 
     190        return -161; 
     191    } 
     192 
     193    status = pj_sem_destroy(sem); 
     194    if (status != PJ_SUCCESS) { 
     195        app_perror("...error: pj_sem_destroy()", status); 
     196        return -163; 
     197    } 
     198 
     199    return 0; 
     200} 
     201#endif  /* PJ_HAS_SEMAPHORE */ 
     202 
     203 
    151204int mutex_test(void) 
    152205{ 
     
    164217        return rc; 
    165218 
     219#if PJ_HAS_SEMAPHORE 
     220    rc = semaphore_test(pool); 
     221    if (rc != 0) 
     222        return rc; 
     223#endif 
     224 
    166225    pj_pool_release(pool); 
    167226 
Note: See TracChangeset for help on using the changeset viewer.