Changeset 4573


Ignore:
Timestamp:
Jul 24, 2013 8:06:59 AM (11 years ago)
Author:
nanang
Message:

Fix #1691: Apply group lock mechanism in NAT detect to avoid deadlock.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjnath/src/pjnath/nat_detect.c

    r4537 r4573  
    7676{ 
    7777    pj_pool_t               *pool; 
    78     pj_mutex_t              *mutex; 
     78    pj_grp_lock_t           *grp_lock; 
    7979 
    8080    pj_timer_heap_t         *timer_heap; 
     
    134134                             pj_timer_entry *te); 
    135135static void sess_destroy(nat_detect_session *sess); 
    136  
     136static void sess_on_destroy(void *member); 
    137137 
    138138/* 
     
    234234    sess->cb = cb; 
    235235 
    236     status = pj_mutex_create_recursive(pool, pool->obj_name, &sess->mutex); 
    237     if (status != PJ_SUCCESS) 
    238         goto on_error; 
    239      
     236    status = pj_grp_lock_create(pool, NULL, &sess->grp_lock); 
     237    if (status != PJ_SUCCESS) { 
     238        /* Group lock not created yet, just destroy pool and return */ 
     239        pj_pool_release(pool); 
     240        return status; 
     241    } 
     242 
     243    pj_grp_lock_add_ref(sess->grp_lock); 
     244    pj_grp_lock_add_handler(sess->grp_lock, pool, sess, &sess_on_destroy); 
     245 
    240246    pj_memcpy(&sess->server, server, sizeof(pj_sockaddr_in)); 
    241247 
     
    295301    ioqueue_cb.on_read_complete = &on_read_complete; 
    296302 
    297     status = pj_ioqueue_register_sock(sess->pool, stun_cfg->ioqueue,  
    298                                       sess->sock, sess, &ioqueue_cb, 
    299                                       &sess->key); 
     303    status = pj_ioqueue_register_sock2(sess->pool, stun_cfg->ioqueue,  
     304                                       sess->sock, sess->grp_lock, sess, 
     305                                       &ioqueue_cb, &sess->key); 
    300306    if (status != PJ_SUCCESS) 
    301307        goto on_error; 
     
    308314    sess_cb.on_send_msg = &on_send_msg; 
    309315    status = pj_stun_session_create(stun_cfg, pool->obj_name, &sess_cb, 
    310                                     PJ_FALSE, NULL, &sess->stun_sess); 
     316                                    PJ_FALSE, sess->grp_lock, &sess->stun_sess); 
    311317    if (status != PJ_SUCCESS) 
    312318        goto on_error; 
     
    339345    if (sess->stun_sess) {  
    340346        pj_stun_session_destroy(sess->stun_sess); 
     347        sess->stun_sess = NULL; 
    341348    } 
    342349 
    343350    if (sess->key) { 
    344351        pj_ioqueue_unregister(sess->key); 
     352        sess->key = NULL; 
     353        sess->sock = PJ_INVALID_SOCKET; 
    345354    } else if (sess->sock && sess->sock != PJ_INVALID_SOCKET) { 
    346355        pj_sock_close(sess->sock); 
    347     } 
    348  
    349     if (sess->mutex) { 
    350         pj_mutex_destroy(sess->mutex); 
    351     } 
    352  
     356        sess->sock = PJ_INVALID_SOCKET; 
     357    } 
     358 
     359    if (sess->grp_lock) { 
     360        pj_grp_lock_dec_ref(sess->grp_lock); 
     361    } 
     362} 
     363 
     364static void sess_on_destroy(void *member) 
     365{ 
     366    nat_detect_session *sess = (nat_detect_session*)member; 
    353367    if (sess->pool) { 
    354368        pj_pool_release(sess->pool); 
    355369    } 
    356370} 
    357  
    358371 
    359372static void end_session(nat_detect_session *sess, 
     
    403416    pj_assert(sess != NULL); 
    404417 
    405     pj_mutex_lock(sess->mutex); 
     418    pj_grp_lock_acquire(sess->grp_lock); 
     419 
     420    /* Ignore packet when STUN session has been destroyed */ 
     421    if (!sess->stun_sess) 
     422        goto on_return; 
    406423 
    407424    if (bytes_read < 0) { 
     
    436453 
    437454on_return: 
    438     pj_mutex_unlock(sess->mutex); 
     455    pj_grp_lock_release(sess->grp_lock); 
    439456} 
    440457 
     
    491508    sess = (nat_detect_session*) pj_stun_session_get_user_data(stun_sess); 
    492509 
    493     pj_mutex_lock(sess->mutex); 
     510    pj_grp_lock_acquire(sess->grp_lock); 
    494511 
    495512    /* Find errors in the response */ 
     
    787804 
    788805on_return: 
    789     pj_mutex_unlock(sess->mutex); 
     806    pj_grp_lock_release(sess->grp_lock); 
    790807} 
    791808 
     
    866883 
    867884    if (te->id == TIMER_DESTROY) { 
    868         pj_mutex_lock(sess->mutex); 
     885        pj_grp_lock_acquire(sess->grp_lock); 
    869886        pj_ioqueue_unregister(sess->key); 
    870887        sess->key = NULL; 
    871888        sess->sock = PJ_INVALID_SOCKET; 
    872889        te->id = 0; 
    873         pj_mutex_unlock(sess->mutex); 
     890        pj_grp_lock_release(sess->grp_lock); 
    874891 
    875892        sess_destroy(sess); 
     
    879896        pj_bool_t next_timer; 
    880897 
    881         pj_mutex_lock(sess->mutex); 
     898        pj_grp_lock_acquire(sess->grp_lock); 
    882899 
    883900        next_timer = PJ_FALSE; 
     
    904921        } 
    905922 
    906         pj_mutex_unlock(sess->mutex); 
     923        pj_grp_lock_release(sess->grp_lock); 
    907924 
    908925    } else { 
Note: See TracChangeset for help on using the changeset viewer.