Ignore:
Timestamp:
Feb 21, 2013 11:18:36 AM (11 years ago)
Author:
bennylp
Message:

Fixed #1616: Implementation of Group lock and other foundation in PJLIB for fixing synchronization issues

File:
1 edited

Legend:

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

    r3999 r4359  
    9898struct pj_event_t 
    9999{ 
    100     char                obj_name[PJ_MAX_OBJ_NAME]; 
     100    enum event_state { 
     101        EV_STATE_OFF, 
     102        EV_STATE_SET, 
     103        EV_STATE_PULSED 
     104    } state; 
     105 
     106    pj_mutex_t          mutex; 
     107    pthread_cond_t      cond; 
     108 
     109    pj_bool_t           auto_reset; 
     110    unsigned            threads_waiting; 
     111    unsigned            threads_to_release; 
    101112}; 
    102113#endif  /* PJ_HAS_EVENT_OBJ */ 
     
    17011712                                    pj_event_t **ptr_event) 
    17021713{ 
    1703     pj_assert(!"Not supported!"); 
    1704     PJ_UNUSED_ARG(pool); 
    1705     PJ_UNUSED_ARG(name); 
    1706     PJ_UNUSED_ARG(manual_reset); 
    1707     PJ_UNUSED_ARG(initial); 
    1708     PJ_UNUSED_ARG(ptr_event); 
    1709     return PJ_EINVALIDOP; 
     1714    pj_event_t *event; 
     1715 
     1716    event = PJ_POOL_ALLOC_T(pool, pj_event_t); 
     1717 
     1718    init_mutex(&event->mutex, name, PJ_MUTEX_SIMPLE); 
     1719    pthread_cond_init(&event->cond, 0); 
     1720    event->auto_reset = !manual_reset; 
     1721    event->threads_waiting = 0; 
     1722 
     1723    if (initial) { 
     1724        event->state = EV_STATE_SET; 
     1725        event->threads_to_release = 1; 
     1726    } else { 
     1727        event->state = EV_STATE_OFF; 
     1728        event->threads_to_release = 0; 
     1729    } 
     1730 
     1731    *ptr_event = event; 
     1732    return PJ_SUCCESS; 
     1733} 
     1734 
     1735static void event_on_one_release(pj_event_t *event) 
     1736{ 
     1737    if (event->state == EV_STATE_SET) { 
     1738        if (event->auto_reset) { 
     1739            event->threads_to_release = 0; 
     1740            event->state = EV_STATE_OFF; 
     1741        } else { 
     1742            /* Manual reset remains on */ 
     1743        } 
     1744    } else { 
     1745        if (event->auto_reset) { 
     1746            /* Only release one */ 
     1747            event->threads_to_release = 0; 
     1748            event->state = EV_STATE_OFF; 
     1749        } else { 
     1750            event->threads_to_release--; 
     1751            pj_assert(event->threads_to_release >= 0); 
     1752            if (event->threads_to_release==0) 
     1753                event->state = EV_STATE_OFF; 
     1754        } 
     1755    } 
    17101756} 
    17111757 
     
    17151761PJ_DEF(pj_status_t) pj_event_wait(pj_event_t *event) 
    17161762{ 
    1717     PJ_UNUSED_ARG(event); 
    1718     return PJ_EINVALIDOP; 
     1763    pthread_mutex_lock(&event->mutex.mutex); 
     1764    event->threads_waiting++; 
     1765    while (event->state == EV_STATE_OFF) 
     1766        pthread_cond_wait(&event->cond, &event->mutex.mutex); 
     1767    event->threads_waiting--; 
     1768    event_on_one_release(event); 
     1769    pthread_mutex_unlock(&event->mutex.mutex); 
     1770    return PJ_SUCCESS; 
    17191771} 
    17201772 
     
    17241776PJ_DEF(pj_status_t) pj_event_trywait(pj_event_t *event) 
    17251777{ 
    1726     PJ_UNUSED_ARG(event); 
    1727     return PJ_EINVALIDOP; 
     1778    pj_status_t status; 
     1779 
     1780    pthread_mutex_lock(&event->mutex.mutex); 
     1781    status = event->state != EV_STATE_OFF ? PJ_SUCCESS : -1; 
     1782    if (status==PJ_SUCCESS) { 
     1783        event_on_one_release(event); 
     1784    } 
     1785    pthread_mutex_unlock(&event->mutex.mutex); 
     1786 
     1787    return status; 
    17281788} 
    17291789 
     
    17331793PJ_DEF(pj_status_t) pj_event_set(pj_event_t *event) 
    17341794{ 
    1735     PJ_UNUSED_ARG(event); 
    1736     return PJ_EINVALIDOP; 
     1795    pthread_mutex_lock(&event->mutex.mutex); 
     1796    event->threads_to_release = 1; 
     1797    event->state = EV_STATE_SET; 
     1798    if (event->auto_reset) 
     1799        pthread_cond_signal(&event->cond); 
     1800    else 
     1801        pthread_cond_broadcast(&event->cond); 
     1802    pthread_mutex_unlock(&event->mutex.mutex); 
     1803    return PJ_SUCCESS; 
    17371804} 
    17381805 
     
    17421809PJ_DEF(pj_status_t) pj_event_pulse(pj_event_t *event) 
    17431810{ 
    1744     PJ_UNUSED_ARG(event); 
    1745     return PJ_EINVALIDOP; 
     1811    pthread_mutex_lock(&event->mutex.mutex); 
     1812    if (event->threads_waiting) { 
     1813        event->threads_to_release = event->auto_reset ? 1 : 
     1814                                        event->threads_waiting; 
     1815        event->state = EV_STATE_PULSED; 
     1816        if (event->threads_to_release==1) 
     1817            pthread_cond_signal(&event->cond); 
     1818        else 
     1819            pthread_cond_broadcast(&event->cond); 
     1820    } 
     1821    pthread_mutex_unlock(&event->mutex.mutex); 
     1822    return PJ_SUCCESS; 
    17461823} 
    17471824 
     
    17511828PJ_DEF(pj_status_t) pj_event_reset(pj_event_t *event) 
    17521829{ 
    1753     PJ_UNUSED_ARG(event); 
    1754     return PJ_EINVALIDOP; 
     1830    pthread_mutex_lock(&event->mutex.mutex); 
     1831    event->state = EV_STATE_OFF; 
     1832    event->threads_to_release = 0; 
     1833    pthread_mutex_unlock(&event->mutex.mutex); 
     1834    return PJ_SUCCESS; 
    17551835} 
    17561836 
     
    17601840PJ_DEF(pj_status_t) pj_event_destroy(pj_event_t *event) 
    17611841{ 
    1762     PJ_UNUSED_ARG(event); 
    1763     return PJ_EINVALIDOP; 
     1842    pj_mutex_destroy(&event->mutex); 
     1843    pthread_cond_destroy(&event->cond); 
     1844    return PJ_SUCCESS; 
    17641845} 
    17651846 
Note: See TracChangeset for help on using the changeset viewer.