Fixed ticket #529: memory leak on Symbian and possibly handle leaks on all platforms when application quits while transactions have not been terminated

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@2127 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjsip/src/pjsip/sip_endpoint.c b/pjsip/src/pjsip/sip_endpoint.c
index 5b983f1..8d2f2ed 100644
--- a/pjsip/src/pjsip/sip_endpoint.c
+++ b/pjsip/src/pjsip/sip_endpoint.c
@@ -105,6 +105,8 @@
 			     pj_status_t, pjsip_rx_data*);
 static pj_status_t endpt_on_tx_msg( pjsip_endpoint *endpt,
 				    pjsip_tx_data *tdata );
+static pj_status_t unload_module(pjsip_endpoint *endpt,
+				 pjsip_module *mod);
 
 /* Defined in sip_parser.c */
 void init_sip_parser(void);
@@ -240,10 +242,33 @@
 	if (status != PJ_SUCCESS) goto on_return;
     }
 
+    /* Unload module */
+    status = unload_module(endpt, mod);
+
+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;
+}
+
+static pj_status_t unload_module(pjsip_endpoint *endpt,
+				 pjsip_module *mod)
+{
+    pj_status_t status;
+
     /* Try to unload the module. */
     if (mod->unload) {
 	status = (*mod->unload)();
-	if (status != PJ_SUCCESS) goto on_return;
+	if (status != PJ_SUCCESS) 
+	    return status;
     }
 
     /* Module MUST NOT set module ID to -1. */
@@ -264,17 +289,6 @@
     PJ_LOG(4,(THIS_FILE, "Module \"%.*s\" unregistered", 
 	      (int)mod->name.slen, mod->name.ptr));
 
-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;
 }
 
@@ -552,11 +566,21 @@
 
     PJ_LOG(5, (THIS_FILE, "Destroying endpoing instance.."));
 
-    /* Unregister modules. */
+    /* Phase 1: stop all modules */
     mod = endpt->module_list.prev;
     while (mod != &endpt->module_list) {
 	pjsip_module *prev = mod->prev;
-	pjsip_endpt_unregister_module(endpt, mod);
+	if (mod->stop) {
+	    (*mod->stop)();
+	}
+	mod = prev;
+    }
+
+    /* Phase 2: unload modules. */
+    mod = endpt->module_list.prev;
+    while (mod != &endpt->module_list) {
+	pjsip_module *prev = mod->prev;
+	unload_module(endpt, mod);
 	mod = prev;
     }
 
diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c
index b0aef75..7792092 100644
--- a/pjsip/src/pjsip/sip_transaction.c
+++ b/pjsip/src/pjsip/sip_transaction.c
@@ -677,6 +677,7 @@
 				 pj_hash_this(mod_tsx_layer.htable, it);
 	pj_hash_iterator_t *next = pj_hash_next(mod_tsx_layer.htable, it);
 	if (tsx) {
+	    pjsip_tsx_terminate(tsx, PJSIP_SC_SERVICE_UNAVAILABLE);
 	    mod_tsx_layer_unregister_tsx(tsx);
 	    tsx_destroy(tsx);
 	}