summaryrefslogtreecommitdiff
path: root/pjsip
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2010-01-25 13:42:56 +0000
committerBenny Prijono <bennylp@teluu.com>2010-01-25 13:42:56 +0000
commit31f597e11a1547e0ce2932b02183f8807a6c6722 (patch)
tree69ee18cf67fda25a88f1da66cc07839823e393fa /pjsip
parentbee900b43985446ad579a2642a68ae2461dd2964 (diff)
Initial commit for #1033: Assertion error when shutting down PJSIP while TCP/TLS connect is in progress and a transaction is waiting
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3071 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip')
-rw-r--r--pjsip/include/pjsip/sip_transaction.h5
-rw-r--r--pjsip/include/pjsip/sip_transport.h4
-rw-r--r--pjsip/src/pjsip/sip_transaction.c66
3 files changed, 61 insertions, 14 deletions
diff --git a/pjsip/include/pjsip/sip_transaction.h b/pjsip/include/pjsip/sip_transaction.h
index eb8510ae..febc53c9 100644
--- a/pjsip/include/pjsip/sip_transaction.h
+++ b/pjsip/include/pjsip/sip_transaction.h
@@ -97,7 +97,6 @@ struct pjsip_transaction
pj_str_t transaction_key;/**< Hash table key. */
pj_uint32_t hashed_key; /**< Key's hashed value. */
pj_str_t branch; /**< The branch Id. */
- pjsip_tpselector tp_sel; /**< Transport selector. */
/*
* State and status.
@@ -121,6 +120,10 @@ struct pjsip_transaction
pjsip_response_addr res_addr; /**< Response address. */
unsigned transport_flag; /**< Miscelaneous flag. */
pj_status_t transport_err; /**< Internal error code. */
+ pjsip_tpselector tp_sel; /**< Transport selector. */
+ pjsip_tx_data *pending_tx; /**< Tdata which caused
+ pending transport flag
+ to be set on tsx. */
/*
* Messages and timer.
diff --git a/pjsip/include/pjsip/sip_transport.h b/pjsip/include/pjsip/sip_transport.h
index b971762f..04c5255c 100644
--- a/pjsip/include/pjsip/sip_transport.h
+++ b/pjsip/include/pjsip/sip_transport.h
@@ -569,6 +569,10 @@ struct pjsip_tx_data
*/
pjsip_tpselector tp_sel;
+ /**
+ * Arbitrary data attached by PJSIP modules.
+ */
+ void *mod_data[PJSIP_MAX_MODULE];
};
diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c
index d5be2b97..026220a2 100644
--- a/pjsip/src/pjsip/sip_transaction.c
+++ b/pjsip/src/pjsip/sip_transaction.c
@@ -581,6 +581,15 @@ static pj_status_t mod_tsx_layer_register_tsx( pjsip_transaction *tsx)
*/
static void mod_tsx_layer_unregister_tsx( pjsip_transaction *tsx)
{
+ if (mod_tsx_layer.mod.id == -1) {
+ /* The transaction layer has been unregistered. This could happen
+ * if the transaction was pending on transport and the application
+ * is shutdown. See http://trac.pjsip.org/repos/ticket/1033. In
+ * this case just do nothing.
+ */
+ return;
+ }
+
pj_assert(tsx->transaction_key.slen != 0);
//pj_assert(tsx->state != PJSIP_TSX_STATE_NULL);
@@ -1115,21 +1124,28 @@ static void tsx_set_state( pjsip_transaction *tsx,
if (state == PJSIP_TSX_STATE_TERMINATED) {
pj_time_val timeout = {0, 0};
- /* Reschedule timeout timer to destroy this transaction. */
+ /* If we're still waiting for a message to be sent.. */
if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) {
- tsx->transport_flag |= TSX_HAS_PENDING_DESTROY;
- } else {
- /* Cancel timeout timer. */
- if (tsx->timeout_timer.id != 0) {
- pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer);
- tsx->timeout_timer.id = 0;
- }
+ /* Disassociate ourselves from the outstanding transmit data
+ * so that when the send callback is called we will be able
+ * to ignore that (otherwise we'll get assertion, see
+ * http://trac.pjsip.org/repos/ticket/1033)
+ */
+ tsx->pending_tx->mod_data[mod_tsx_layer.mod.id] = NULL;
+ tsx->pending_tx = NULL;
+ tsx->transport_flag &= ~(TSX_HAS_PENDING_TRANSPORT);
+ }
- tsx->timeout_timer.id = TIMER_ACTIVE;
- pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer,
- &timeout);
+ /* Cancel timeout timer. */
+ if (tsx->timeout_timer.id != 0) {
+ pjsip_endpt_cancel_timer(tsx->endpt, &tsx->timeout_timer);
+ tsx->timeout_timer.id = 0;
}
+ tsx->timeout_timer.id = TIMER_ACTIVE;
+ pjsip_endpt_schedule_timer( tsx->endpt, &tsx->timeout_timer,
+ &timeout);
+
} else if (state == PJSIP_TSX_STATE_DESTROYED) {
@@ -1637,6 +1653,17 @@ static void send_msg_callback( pjsip_send_state *send_state,
pjsip_tx_data *tdata = send_state->tdata;
struct tsx_lock_data lck;
+ /* Check if transaction has cancelled itself from this transmit
+ * notification (https://trac.pjsip.org/repos/ticket/1033).
+ */
+ if (tdata->mod_data[mod_tsx_layer.mod.id] == NULL) {
+ return;
+ }
+
+ /* Reset */
+ tdata->mod_data[mod_tsx_layer.mod.id] = NULL;
+ tsx->pending_tx = NULL;
+
lock_tsx(tsx, &lck);
if (sent > 0) {
@@ -1906,6 +1933,13 @@ static pj_status_t tsx_send_msg( pjsip_transaction *tsx,
*/
pjsip_tx_data_add_ref(tdata);
+ /* Also attach ourselves to the transmit data so that we'll be able
+ * to unregister ourselves from the send notification of this
+ * transmit data.
+ */
+ tdata->mod_data[mod_tsx_layer.mod.id] = tsx;
+ tsx->pending_tx = tdata;
+
/* Begin resolving destination etc to send the message. */
if (tdata->msg->type == PJSIP_REQUEST_MSG) {
@@ -1914,8 +1948,11 @@ static pj_status_t tsx_send_msg( pjsip_transaction *tsx,
&send_msg_callback);
if (status == PJ_EPENDING)
status = PJ_SUCCESS;
- if (status != PJ_SUCCESS)
+ if (status != PJ_SUCCESS) {
pjsip_tx_data_dec_ref(tdata);
+ tdata->mod_data[mod_tsx_layer.mod.id] = NULL;
+ tsx->pending_tx = NULL;
+ }
/* Check if transaction is terminated. */
if (status==PJ_SUCCESS && tsx->state == PJSIP_TSX_STATE_TERMINATED)
@@ -1929,8 +1966,11 @@ static pj_status_t tsx_send_msg( pjsip_transaction *tsx,
&send_msg_callback);
if (status == PJ_EPENDING)
status = PJ_SUCCESS;
- if (status != PJ_SUCCESS)
+ if (status != PJ_SUCCESS) {
pjsip_tx_data_dec_ref(tdata);
+ tdata->mod_data[mod_tsx_layer.mod.id] = NULL;
+ tsx->pending_tx = NULL;
+ }
/* Check if transaction is terminated. */
if (status==PJ_SUCCESS && tsx->state == PJSIP_TSX_STATE_TERMINATED)