diff options
author | Nanang Izzuddin <nanang@teluu.com> | 2013-05-30 09:27:49 +0000 |
---|---|---|
committer | Nanang Izzuddin <nanang@teluu.com> | 2013-05-30 09:27:49 +0000 |
commit | 0bb1e209706fcd5aade892fb38a2a90a9be8185f (patch) | |
tree | 960171665fe18e3267adfd00d468670ed4738e5e /pjsip/src | |
parent | ebfa1a5e90eda4bc52dfa540ec833a77261ab37b (diff) |
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.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4530 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip/src')
-rw-r--r-- | pjsip/src/pjsip-simple/publishc.c | 26 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_transport.c | 71 |
2 files changed, 77 insertions, 20 deletions
diff --git a/pjsip/src/pjsip-simple/publishc.c b/pjsip/src/pjsip-simple/publishc.c index af8d0b3e..fcb412dd 100644 --- a/pjsip/src/pjsip-simple/publishc.c +++ b/pjsip/src/pjsip-simple/publishc.c @@ -61,7 +61,8 @@ const pjsip_method pjsip_publish_method = */ typedef struct pending_publish { - PJ_DECL_LIST_MEMBER(pjsip_tx_data); + PJ_DECL_LIST_MEMBER(struct pending_publish); + pjsip_tx_data *tdata; } pending_publish; @@ -108,6 +109,7 @@ struct pjsip_publishc /* Pending PUBLISH request */ pending_publish pending_reqs; + pending_publish pending_reqs_empty; }; @@ -180,6 +182,7 @@ PJ_DEF(pj_status_t) pjsip_publishc_create( pjsip_endpoint *endpt, } pj_memcpy(&pubc->opt, opt, sizeof(*opt)); pj_list_init(&pubc->pending_reqs); + pj_list_init(&pubc->pending_reqs_empty); status = pj_mutex_create_recursive(pubc->pool, "pubc%p", &pubc->mutex); if (status != PJ_SUCCESS) { @@ -683,8 +686,14 @@ static void tsx_callback(void *token, pjsip_event *event) /* If we have pending request(s), send them now */ pj_mutex_lock(pubc->mutex); while (!pj_list_empty(&pubc->pending_reqs)) { - pjsip_tx_data *tdata = pubc->pending_reqs.next; - pj_list_erase(tdata); + pending_publish *pp = pubc->pending_reqs.next; + pjsip_tx_data *tdata = pp->tdata; + + /* Remove the request from pending request list, + * and keep the unused entry into pending_reqs_empty pool. + */ + pj_list_erase(pp); + pj_list_push_back(&pubc->pending_reqs_empty, pp); /* Add SIP-If-Match if we have etag and the request doesn't have * one (http://trac.pjsip.org/repos/ticket/996) @@ -712,7 +721,6 @@ static void tsx_callback(void *token, pjsip_event *event) status = pjsip_publishc_send(pubc, tdata); if (status == PJ_EPENDING) { pj_assert(!"Not expected"); - pj_list_erase(tdata); pjsip_tx_data_dec_ref(tdata); } else if (status == PJ_SUCCESS) { break; @@ -744,7 +752,15 @@ PJ_DEF(pj_status_t) pjsip_publishc_send(pjsip_publishc *pubc, pj_mutex_lock(pubc->mutex); if (pubc->pending_tsx) { if (pubc->opt.queue_request) { - pj_list_push_back(&pubc->pending_reqs, tdata); + pending_publish *pp = NULL; + if (pj_list_empty(&pubc->pending_reqs_empty)) { + pp = PJ_POOL_ZALLOC_T(pubc->pool, pending_publish); + } else { + pp = pubc->pending_reqs_empty.next; + pj_list_erase(pp); + } + pp->tdata = tdata; + pj_list_push_back(&pubc->pending_reqs, pp); pj_mutex_unlock(pubc->mutex); PJ_LOG(4,(THIS_FILE, "Request is queued, pubc has another " "transaction pending")); diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c index ef2de49e..d1ee6178 100644 --- a/pjsip/src/pjsip/sip_transport.c +++ b/pjsip/src/pjsip/sip_transport.c @@ -92,6 +92,11 @@ struct pjsip_tpmgr void (*on_rx_msg)(pjsip_endpoint*, pj_status_t, pjsip_rx_data*); pj_status_t (*on_tx_msg)(pjsip_endpoint*, pjsip_tx_data*); pjsip_tp_state_callback tp_state_cb; + + /* Transmit data list, for transmit data cleanup when transport manager + * is destroyed. + */ + pjsip_tx_data tdata_list; }; @@ -419,6 +424,14 @@ PJ_DEF(pj_status_t) pjsip_tx_data_create( pjsip_tpmgr *mgr, } pj_ioqueue_op_key_init(&tdata->op_key.key, sizeof(tdata->op_key.key)); + pj_list_init(tdata); + +#if defined(PJSIP_HAS_TX_DATA_LIST) && PJSIP_HAS_TX_DATA_LIST!=0 + /* Append this just created tdata to transmit buffer list */ + pj_lock_acquire(mgr->lock); + pj_list_push_back(&mgr->tdata_list, tdata); + pj_lock_release(mgr->lock); +#endif #if defined(PJ_DEBUG) && PJ_DEBUG!=0 pj_atomic_inc( tdata->mgr->tdata_counter ); @@ -437,6 +450,27 @@ PJ_DEF(void) pjsip_tx_data_add_ref( pjsip_tx_data *tdata ) pj_atomic_inc(tdata->ref_cnt); } +static void tx_data_destroy(pjsip_tx_data *tdata) +{ + PJ_LOG(5,(tdata->obj_name, "Destroying txdata %s", + pjsip_tx_data_get_info(tdata))); + pjsip_tpselector_dec_ref(&tdata->tp_sel); +#if defined(PJ_DEBUG) && PJ_DEBUG!=0 + pj_atomic_dec( tdata->mgr->tdata_counter ); +#endif + +#if defined(PJSIP_HAS_TX_DATA_LIST) && PJSIP_HAS_TX_DATA_LIST!=0 + /* Remove this tdata from transmit buffer list */ + pj_lock_acquire(tdata->mgr->lock); + pj_list_erase(tdata); + pj_lock_release(tdata->mgr->lock); +#endif + + pj_atomic_destroy( tdata->ref_cnt ); + pj_lock_destroy( tdata->lock ); + pjsip_endpt_release_pool( tdata->mgr->endpt, tdata->pool ); +} + /* * Decrease transport data reference, destroy it when the reference count * reaches zero. @@ -445,15 +479,7 @@ PJ_DEF(pj_status_t) pjsip_tx_data_dec_ref( pjsip_tx_data *tdata ) { pj_assert( pj_atomic_get(tdata->ref_cnt) > 0); if (pj_atomic_dec_and_get(tdata->ref_cnt) <= 0) { - PJ_LOG(5,(tdata->obj_name, "Destroying txdata %s", - pjsip_tx_data_get_info(tdata))); - pjsip_tpselector_dec_ref(&tdata->tp_sel); -#if defined(PJ_DEBUG) && PJ_DEBUG!=0 - pj_atomic_dec( tdata->mgr->tdata_counter ); -#endif - pj_atomic_destroy( tdata->ref_cnt ); - pj_lock_destroy( tdata->lock ); - pjsip_endpt_release_pool( tdata->mgr->endpt, tdata->pool ); + tx_data_destroy(tdata); return PJSIP_EBUFDESTROYED; } else { return PJ_SUCCESS; @@ -1207,6 +1233,7 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_create( pj_pool_t *pool, mgr->on_rx_msg = rx_cb; mgr->on_tx_msg = tx_cb; pj_list_init(&mgr->factory_list); + pj_list_init(&mgr->tdata_list); mgr->table = pj_hash_create(pool, PJSIP_TPMGR_HTABLE_SIZE); if (!mgr->table) @@ -1497,12 +1524,6 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_destroy( pjsip_tpmgr *mgr ) } pj_lock_release(mgr->lock); - pj_lock_destroy(mgr->lock); - - /* Unregister mod_msg_print. */ - if (mod_msg_print.id != -1) { - pjsip_endpt_unregister_module(endpt, &mod_msg_print); - } #if defined(PJ_DEBUG) && PJ_DEBUG!=0 /* If you encounter assert error on this line, it means there are @@ -1518,6 +1539,26 @@ PJ_DEF(pj_status_t) pjsip_tpmgr_destroy( pjsip_tpmgr *mgr ) pj_atomic_destroy(mgr->tdata_counter); #endif + /* + * Destroy any dangling transmit buffer. + */ + if (!pj_list_empty(&mgr->tdata_list)) { + pjsip_tx_data *tdata = mgr->tdata_list.next; + while (tdata != &mgr->tdata_list) { + pjsip_tx_data *next = tdata->next; + tx_data_destroy(tdata); + tdata = next; + } + PJ_LOG(3,(THIS_FILE, "Cleaned up dangling transmit buffer(s).")); + } + + pj_lock_destroy(mgr->lock); + + /* Unregister mod_msg_print. */ + if (mod_msg_print.id != -1) { + pjsip_endpt_unregister_module(endpt, &mod_msg_print); + } + return PJ_SUCCESS; } |