Changeset 4530


Ignore:
Timestamp:
May 30, 2013 9:27:49 AM (7 years ago)
Author:
nanang
Message:

Fixed #1671:

  • Transport manager maintains transmit buffer instance list, so any dangling transmit buffer will be freed when transport manager is destroyed. This is configurable via PJSIP_HAS_TX_DATA_LIST, the default is zero/disabled.
  • Updated publish client subscription to not use the 'internal' pjsip_tx_data list structure.
Location:
pjproject/trunk/pjsip
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/include/pjsip/sip_config.h

    r4506 r4530  
    11331133 
    11341134 
     1135/** 
     1136 * Specify whether transport manager should maintain a list of transmit 
     1137 * buffer instances, so any possible dangling instance can be cleaned up 
     1138 * when the transport manager is shutdown (see also ticket #1671). 
     1139 * Note that this feature will have slight impact on the performance as 
     1140 * mutex is employed in updating the list, i.e: on creation and destruction 
     1141 * of transmit data. 
     1142 * 
     1143 * Default: 0 (no) 
     1144 */ 
     1145#ifndef PJSIP_HAS_TX_DATA_LIST 
     1146#   define PJSIP_HAS_TX_DATA_LIST               0 
     1147#endif 
     1148 
     1149 
    11351150PJ_END_DECL 
    11361151 
  • pjproject/trunk/pjsip/src/pjsip-simple/publishc.c

    r4206 r4530  
    6262typedef struct pending_publish 
    6363{ 
    64     PJ_DECL_LIST_MEMBER(pjsip_tx_data); 
     64    PJ_DECL_LIST_MEMBER(struct pending_publish); 
     65    pjsip_tx_data               *tdata; 
    6566} pending_publish; 
    6667 
     
    109110    /* Pending PUBLISH request */ 
    110111    pending_publish              pending_reqs; 
     112    pending_publish              pending_reqs_empty; 
    111113}; 
    112114 
     
    181183    pj_memcpy(&pubc->opt, opt, sizeof(*opt)); 
    182184    pj_list_init(&pubc->pending_reqs); 
     185    pj_list_init(&pubc->pending_reqs_empty); 
    183186 
    184187    status = pj_mutex_create_recursive(pubc->pool, "pubc%p", &pubc->mutex); 
     
    684687        pj_mutex_lock(pubc->mutex); 
    685688        while (!pj_list_empty(&pubc->pending_reqs)) { 
    686             pjsip_tx_data *tdata = pubc->pending_reqs.next; 
    687             pj_list_erase(tdata); 
     689            pending_publish *pp = pubc->pending_reqs.next; 
     690            pjsip_tx_data *tdata = pp->tdata; 
     691 
     692            /* Remove the request from pending request list, 
     693             * and keep the unused entry into pending_reqs_empty pool. 
     694             */ 
     695            pj_list_erase(pp); 
     696            pj_list_push_back(&pubc->pending_reqs_empty, pp); 
    688697 
    689698            /* Add SIP-If-Match if we have etag and the request doesn't have 
     
    713722            if (status == PJ_EPENDING) { 
    714723                pj_assert(!"Not expected"); 
    715                 pj_list_erase(tdata); 
    716724                pjsip_tx_data_dec_ref(tdata); 
    717725            } else if (status == PJ_SUCCESS) { 
     
    745753    if (pubc->pending_tsx) { 
    746754        if (pubc->opt.queue_request) { 
    747             pj_list_push_back(&pubc->pending_reqs, tdata); 
     755            pending_publish *pp = NULL; 
     756            if (pj_list_empty(&pubc->pending_reqs_empty)) { 
     757                pp = PJ_POOL_ZALLOC_T(pubc->pool, pending_publish); 
     758            } else { 
     759                pp = pubc->pending_reqs_empty.next; 
     760                pj_list_erase(pp); 
     761            } 
     762            pp->tdata = tdata; 
     763            pj_list_push_back(&pubc->pending_reqs, pp); 
    748764            pj_mutex_unlock(pubc->mutex); 
    749765            PJ_LOG(4,(THIS_FILE, "Request is queued, pubc has another " 
  • pjproject/trunk/pjsip/src/pjsip/sip_transport.c

    r4529 r4530  
    9393    pj_status_t    (*on_tx_msg)(pjsip_endpoint*, pjsip_tx_data*); 
    9494    pjsip_tp_state_callback tp_state_cb; 
     95 
     96    /* Transmit data list, for transmit data cleanup when transport manager 
     97     * is destroyed. 
     98     */ 
     99    pjsip_tx_data    tdata_list; 
    95100}; 
    96101 
     
    420425 
    421426    pj_ioqueue_op_key_init(&tdata->op_key.key, sizeof(tdata->op_key.key)); 
     427    pj_list_init(tdata); 
     428 
     429#if defined(PJSIP_HAS_TX_DATA_LIST) && PJSIP_HAS_TX_DATA_LIST!=0 
     430    /* Append this just created tdata to transmit buffer list */ 
     431    pj_lock_acquire(mgr->lock); 
     432    pj_list_push_back(&mgr->tdata_list, tdata); 
     433    pj_lock_release(mgr->lock); 
     434#endif 
    422435 
    423436#if defined(PJ_DEBUG) && PJ_DEBUG!=0 
     
    438451} 
    439452 
     453static void tx_data_destroy(pjsip_tx_data *tdata) 
     454{ 
     455    PJ_LOG(5,(tdata->obj_name, "Destroying txdata %s", 
     456              pjsip_tx_data_get_info(tdata))); 
     457    pjsip_tpselector_dec_ref(&tdata->tp_sel); 
     458#if defined(PJ_DEBUG) && PJ_DEBUG!=0 
     459    pj_atomic_dec( tdata->mgr->tdata_counter ); 
     460#endif 
     461 
     462#if defined(PJSIP_HAS_TX_DATA_LIST) && PJSIP_HAS_TX_DATA_LIST!=0 
     463    /* Remove this tdata from transmit buffer list */ 
     464    pj_lock_acquire(tdata->mgr->lock); 
     465    pj_list_erase(tdata); 
     466    pj_lock_release(tdata->mgr->lock); 
     467#endif 
     468 
     469    pj_atomic_destroy( tdata->ref_cnt ); 
     470    pj_lock_destroy( tdata->lock ); 
     471    pjsip_endpt_release_pool( tdata->mgr->endpt, tdata->pool ); 
     472} 
     473 
    440474/* 
    441475 * Decrease transport data reference, destroy it when the reference count 
     
    446480    pj_assert( pj_atomic_get(tdata->ref_cnt) > 0); 
    447481    if (pj_atomic_dec_and_get(tdata->ref_cnt) <= 0) { 
    448         PJ_LOG(5,(tdata->obj_name, "Destroying txdata %s", 
    449                   pjsip_tx_data_get_info(tdata))); 
    450         pjsip_tpselector_dec_ref(&tdata->tp_sel); 
    451 #if defined(PJ_DEBUG) && PJ_DEBUG!=0 
    452         pj_atomic_dec( tdata->mgr->tdata_counter ); 
    453 #endif 
    454         pj_atomic_destroy( tdata->ref_cnt ); 
    455         pj_lock_destroy( tdata->lock ); 
    456         pjsip_endpt_release_pool( tdata->mgr->endpt, tdata->pool ); 
     482        tx_data_destroy(tdata); 
    457483        return PJSIP_EBUFDESTROYED; 
    458484    } else { 
     
    12081234    mgr->on_tx_msg = tx_cb; 
    12091235    pj_list_init(&mgr->factory_list); 
     1236    pj_list_init(&mgr->tdata_list); 
    12101237 
    12111238    mgr->table = pj_hash_create(pool, PJSIP_TPMGR_HTABLE_SIZE); 
     
    14981525 
    14991526    pj_lock_release(mgr->lock); 
    1500     pj_lock_destroy(mgr->lock); 
    1501  
    1502     /* Unregister mod_msg_print. */ 
    1503     if (mod_msg_print.id != -1) { 
    1504         pjsip_endpt_unregister_module(endpt, &mod_msg_print); 
    1505     } 
    15061527 
    15071528#if defined(PJ_DEBUG) && PJ_DEBUG!=0 
     
    15181539    pj_atomic_destroy(mgr->tdata_counter); 
    15191540#endif 
     1541 
     1542    /* 
     1543     * Destroy any dangling transmit buffer. 
     1544     */ 
     1545    if (!pj_list_empty(&mgr->tdata_list)) { 
     1546        pjsip_tx_data *tdata = mgr->tdata_list.next; 
     1547        while (tdata != &mgr->tdata_list) { 
     1548            pjsip_tx_data *next = tdata->next; 
     1549            tx_data_destroy(tdata); 
     1550            tdata = next; 
     1551        } 
     1552        PJ_LOG(3,(THIS_FILE, "Cleaned up dangling transmit buffer(s).")); 
     1553    } 
     1554 
     1555    pj_lock_destroy(mgr->lock); 
     1556 
     1557    /* Unregister mod_msg_print. */ 
     1558    if (mod_msg_print.id != -1) { 
     1559        pjsip_endpt_unregister_module(endpt, &mod_msg_print); 
     1560    } 
    15201561 
    15211562    return PJ_SUCCESS; 
Note: See TracChangeset for help on using the changeset viewer.