From cbb6c140cf6e47e65b31b93009cfe39916933009 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Tue, 18 Jul 2006 00:10:53 +0000 Subject: Fixed several bugs related to TCP: git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@610 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip/src/pjsip/sip_endpoint.c | 15 ++++++++++++++- pjsip/src/pjsip/sip_transaction.c | 10 ++++++++++ pjsip/src/pjsip/sip_transport_tcp.c | 32 +++++++++++++++++++++++--------- 3 files changed, 47 insertions(+), 10 deletions(-) (limited to 'pjsip') diff --git a/pjsip/src/pjsip/sip_endpoint.c b/pjsip/src/pjsip/sip_endpoint.c index a00c1af7..aedab9d7 100644 --- a/pjsip/src/pjsip/sip_endpoint.c +++ b/pjsip/src/pjsip/sip_endpoint.c @@ -282,6 +282,15 @@ PJ_DEF(pj_status_t) pjsip_endpt_unregister_module( pjsip_endpoint *endpt, on_return: pj_rwmutex_unlock_write(endpt->mod_mutex); + + if (status != PJ_SUCCESS) { + char errmsg[PJ_ERR_MSG_SIZE]; + + pj_strerror(status, errmsg, sizeof(errmsg)); + PJ_LOG(3,(THIS_FILE, "Module \"%.*s\" can not be unregistered: %s", + (int)mod->name.slen, mod->name.ptr, errmsg)); + } + return status; } @@ -526,8 +535,11 @@ PJ_DEF(void) pjsip_endpt_destroy(pjsip_endpoint *endpt) PJ_LOG(5, (THIS_FILE, "Destroying endpoing instance..")); /* Unregister modules. */ - while ((mod=endpt->module_list.prev) != &endpt->module_list) { + mod = endpt->module_list.prev; + while (mod != &endpt->module_list) { + pjsip_module *prev = mod->prev; pjsip_endpt_unregister_module(endpt, mod); + mod = prev; } /* Shutdown and destroy all transports. */ @@ -595,6 +607,7 @@ PJ_DEF(void) pjsip_endpt_release_pool( pjsip_endpoint *endpt, pj_pool_t *pool ) */ pj_pool_release( pool ); + PJ_UNUSED_ARG(endpt); /* pj_mutex_unlock(endpt->mutex); */ diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c index 17e3ad15..6f714f2a 100644 --- a/pjsip/src/pjsip/sip_transaction.c +++ b/pjsip/src/pjsip/sip_transaction.c @@ -648,6 +648,15 @@ static pj_status_t mod_tsx_layer_stop(void) */ static pj_status_t mod_tsx_layer_unload(void) { + /* Only self destroy when there's no transaction in the table. + * Transaction may refuse to destroy when it has pending + * transmission. If we destroy the module now, application will + * crash when the pending transaction finally got error response + * from transport and when it tries to unregister itself. + */ + if (pj_hash_count(mod_tsx_layer.htable) != 0) + return PJ_EBUSY; + /* Destroy mutex. */ pj_mutex_destroy(mod_tsx_layer.mutex); @@ -927,6 +936,7 @@ static void tsx_destroy( pjsip_transaction *tsx ) /* Refuse to destroy transaction if it has pending resolving. */ if (tsx->transport_flag & TSX_HAS_PENDING_TRANSPORT) { tsx->transport_flag |= TSX_HAS_PENDING_DESTROY; + tsx->tsx_user = NULL; PJ_LOG(4,(tsx->obj_name, "Will destroy later because transport is " "in progress")); return; diff --git a/pjsip/src/pjsip/sip_transport_tcp.c b/pjsip/src/pjsip/sip_transport_tcp.c index dc384d10..c9b92ad4 100644 --- a/pjsip/src/pjsip/sip_transport_tcp.c +++ b/pjsip/src/pjsip/sip_transport_tcp.c @@ -1240,15 +1240,6 @@ static void on_connect_complete(pj_ioqueue_key_t *key, tcp = pj_ioqueue_get_user_data(key); - PJ_LOG(4,(tcp->base.obj_name, - "TCP transport %.*s:%d is connected to %.*s:%d", - (int)tcp->base.local_name.host.slen, - tcp->base.local_name.host.ptr, - tcp->base.local_name.port, - (int)tcp->base.remote_name.host.slen, - tcp->base.remote_name.host.ptr, - tcp->base.remote_name.port)); - /* Mark that pending connect() operation has completed. */ tcp->has_pending_connect = PJ_FALSE; @@ -1257,6 +1248,19 @@ static void on_connect_complete(pj_ioqueue_key_t *key, tcp_perror(tcp->base.obj_name, "TCP connect() error", status); + /* Cancel all delayed transmits */ + while (!pj_list_empty(&tcp->delayed_list)) { + struct delayed_tdata *pending_tx; + pj_ioqueue_op_key_t *op_key; + + pending_tx = tcp->delayed_list.next; + pj_list_erase(pending_tx); + + op_key = (pj_ioqueue_op_key_t*)pending_tx->tdata_op_key; + + on_write_complete(tcp->key, op_key, -status); + } + /* We can not destroy the transport since high level objects may * still keep reference to this transport. So we can only * instruct transport manager to gracefully start the shutdown @@ -1267,6 +1271,16 @@ static void on_connect_complete(pj_ioqueue_key_t *key, return; } + PJ_LOG(4,(tcp->base.obj_name, + "TCP transport %.*s:%d is connected to %.*s:%d", + (int)tcp->base.local_name.host.slen, + tcp->base.local_name.host.ptr, + tcp->base.local_name.port, + (int)tcp->base.remote_name.host.slen, + tcp->base.remote_name.host.ptr, + tcp->base.remote_name.port)); + + /* Update (again) local address, just in case local address currently * set is different now that the socket is connected (could happen * on some systems, like old Win32 probably?). -- cgit v1.2.3