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);
}