Ignore:
Timestamp:
Jun 19, 2014 9:42:02 AM (8 years ago)
Author:
nanang
Message:

Fix #1773: Added group lock to SIP transport to avoid race condition between transport callback and destroy.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/src/pjsip/sip_transport_udp.c

    r4712 r4862  
    7777    int                 is_closing; 
    7878    pj_bool_t           is_paused; 
     79 
     80    /* Group lock to be used by UDP transport and ioqueue key */ 
     81    pj_grp_lock_t      *grp_lock; 
    7982}; 
    8083 
     
    346349} 
    347350 
     351 
     352/* Clean up UDP resources */ 
     353static void udp_on_destroy(void *arg) 
     354{ 
     355    struct udp_transport *tp = (struct udp_transport*)arg; 
     356    int i; 
     357 
     358    /* Destroy rdata */ 
     359    for (i=0; i<tp->rdata_cnt; ++i) { 
     360        pj_pool_release(tp->rdata[i]->tp_info.pool); 
     361    } 
     362 
     363    /* Destroy reference counter. */ 
     364    if (tp->base.ref_cnt) 
     365        pj_atomic_destroy(tp->base.ref_cnt); 
     366 
     367    /* Destroy lock */ 
     368    if (tp->base.lock) 
     369        pj_lock_destroy(tp->base.lock); 
     370 
     371    /* Destroy pool. */ 
     372    pjsip_endpt_release_pool(tp->base.endpt, tp->base.pool); 
     373} 
     374 
     375 
    348376/* 
    349377 * udp_destroy() 
     
    398426    } 
    399427 
    400     /* Destroy rdata */ 
    401     for (i=0; i<tp->rdata_cnt; ++i) { 
    402         pj_pool_release(tp->rdata[i]->tp_info.pool); 
    403     } 
    404  
    405     /* Destroy reference counter. */ 
    406     if (tp->base.ref_cnt) 
    407         pj_atomic_destroy(tp->base.ref_cnt); 
    408  
    409     /* Destroy lock */ 
    410     if (tp->base.lock) 
    411         pj_lock_destroy(tp->base.lock); 
    412  
    413     /* Destroy pool. */ 
    414     pjsip_endpt_release_pool(tp->base.endpt, tp->base.pool); 
     428    if (tp->grp_lock) { 
     429        pj_grp_lock_t *grp_lock = tp->grp_lock; 
     430        tp->grp_lock = NULL; 
     431        pj_grp_lock_dec_ref(grp_lock); 
     432        /* Transport may have been deleted at this point */ 
     433    } else { 
     434        udp_on_destroy(tp); 
     435    } 
    415436 
    416437    return PJ_SUCCESS; 
     
    603624    pj_ioqueue_t *ioqueue; 
    604625    pj_ioqueue_callback ioqueue_cb; 
     626    pj_status_t status; 
    605627 
    606628    /* Ignore if already registered */ 
    607629    if (tp->key != NULL) 
    608630        return PJ_SUCCESS; 
     631 
     632    /* Create group lock */ 
     633    status = pj_grp_lock_create(tp->base.pool, NULL, &tp->grp_lock); 
     634    if (status != PJ_SUCCESS) 
     635        return status; 
     636 
     637    pj_grp_lock_add_ref(tp->grp_lock); 
     638    pj_grp_lock_add_handler(tp->grp_lock, tp->base.pool, tp, &udp_on_destroy); 
    609639     
    610640    /* Register to ioqueue. */ 
     
    614644    ioqueue_cb.on_write_complete = &udp_on_write_complete; 
    615645 
    616     return pj_ioqueue_register_sock(tp->base.pool, ioqueue, tp->sock, tp, 
    617                                     &ioqueue_cb, &tp->key); 
     646    return pj_ioqueue_register_sock2(tp->base.pool, ioqueue, tp->sock, 
     647                                     tp->grp_lock, tp, &ioqueue_cb, &tp->key); 
    618648} 
    619649 
Note: See TracChangeset for help on using the changeset viewer.