summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-11-21 12:39:31 +0000
committerBenny Prijono <bennylp@teluu.com>2006-11-21 12:39:31 +0000
commit271cf23083b38b3f0d12a36bb1f28e458ee43861 (patch)
treed3c5bc170635051fd0aaa3fa41ba26fc421693f1
parentc0cd0b4450fdcf785bb9184b4d6231d452cb8df5 (diff)
Fixed handles leak upon program exit, by introducing pj_shutdown() and pj_atexit(). Also fixed handle leaks in SIP transaction layer and SIP endpoint.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@815 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjlib/include/pj/types.h20
-rw-r--r--pjlib/src/pj/except.c9
-rw-r--r--pjlib/src/pj/os_core_unix.c51
-rw-r--r--pjlib/src/pj/os_core_win32.c51
-rw-r--r--pjlib/src/pj/pool_buf.c16
-rw-r--r--pjsip-apps/src/samples/aectest.c2
-rw-r--r--pjsip-apps/src/samples/confsample.c2
-rw-r--r--pjsip-apps/src/samples/level.c3
-rw-r--r--pjsip-apps/src/samples/pjsip-perf.c3
-rw-r--r--pjsip-apps/src/samples/playfile.c3
-rw-r--r--pjsip-apps/src/samples/playsine.c3
-rw-r--r--pjsip-apps/src/samples/recfile.c3
-rw-r--r--pjsip-apps/src/samples/resampleplay.c3
-rw-r--r--pjsip-apps/src/samples/siprtp.c4
-rw-r--r--pjsip-apps/src/samples/sndinfo.c3
-rw-r--r--pjsip-apps/src/samples/streamutil.c3
-rw-r--r--pjsip-apps/src/samples/tonegen.c3
-rw-r--r--pjsip/src/pjsip/sip_endpoint.c3
-rw-r--r--pjsip/src/pjsip/sip_transaction.c3
-rw-r--r--pjsip/src/pjsua-lib/pjsua_core.c3
-rw-r--r--pjsip/src/pjsua-lib/pjsua_media.c3
21 files changed, 182 insertions, 12 deletions
diff --git a/pjlib/include/pj/types.h b/pjlib/include/pj/types.h
index d15bd60f..df3b92e4 100644
--- a/pjlib/include/pj/types.h
+++ b/pjlib/include/pj/types.h
@@ -291,9 +291,29 @@ typedef int pj_exception_id_t;
* function is to initialize static library data, such as character table used
* in random string generation, and to initialize operating system dependent
* functionality (such as WSAStartup() in Windows).
+ *
+ * @return PJ_SUCCESS on success.
*/
PJ_DECL(pj_status_t) pj_init(void);
+
+/**
+ * Shutdown PJLIB.
+ */
+PJ_DECL(void) pj_shutdown(void);
+
+/**
+ * Register cleanup function to be called by PJLIB when pj_shutdown() is
+ * called.
+ *
+ * @param func The function to be registered.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pj_atexit(void (*func)(void));
+
+
+
/**
* Swap the byte order of an 16bit data.
*
diff --git a/pjlib/src/pj/except.c b/pjlib/src/pj/except.c
index 1074828f..bb21e05b 100644
--- a/pjlib/src/pj/except.c
+++ b/pjlib/src/pj/except.c
@@ -51,6 +51,14 @@ PJ_DEF(void) pj_throw_exception_(int exception_id)
pj_longjmp(handler->state, exception_id);
}
+static void exception_cleanup(void)
+{
+ if (thread_local_id != -1) {
+ pj_thread_local_free(thread_local_id);
+ thread_local_id = -1;
+ }
+}
+
PJ_DEF(void) pj_push_exception_handler_(struct pj_exception_state_t *rec)
{
struct pj_exception_state_t *parent_handler = NULL;
@@ -58,6 +66,7 @@ PJ_DEF(void) pj_push_exception_handler_(struct pj_exception_state_t *rec)
if (thread_local_id == -1) {
pj_thread_local_alloc(&thread_local_id);
pj_assert(thread_local_id != -1);
+ pj_atexit(&exception_cleanup);
}
parent_handler = pj_thread_local_get(thread_local_id);
rec->prev = parent_handler;
diff --git a/pjlib/src/pj/os_core_unix.c b/pjlib/src/pj/os_core_unix.c
index a65c8e89..db55062b 100644
--- a/pjlib/src/pj/os_core_unix.c
+++ b/pjlib/src/pj/os_core_unix.c
@@ -147,13 +147,6 @@ PJ_DEF(pj_status_t) pj_init(void)
guid.ptr = dummy_guid;
pj_generate_unique_string( &guid );
- /* Initialize exception ID for the pool.
- * Must do so after critical section is configured.
- */
- rc = pj_exception_id_alloc("PJLIB/No memory", &PJ_NO_MEMORY_EXCEPTION);
- if (rc != PJ_SUCCESS)
- return rc;
-
/* Startup timestamp */
#if defined(PJ_HAS_HIGH_RES_TIMER) && PJ_HAS_HIGH_RES_TIMER != 0
{
@@ -171,6 +164,50 @@ PJ_DEF(pj_status_t) pj_init(void)
}
/*
+ * pj_atexit()
+ */
+PJ_DEF(pj_status_t) pj_atexit(void (*func)(void))
+{
+ if (atexit_count >= PJ_ARRAY_SIZE(atexit_func))
+ return PJ_ETOOMANY;
+
+ atexit_func[atexit_count++] = func;
+ return PJ_SUCCESS;
+}
+
+/*
+ * pj_shutdown(void)
+ */
+PJ_DEF(void) pj_shutdown()
+{
+ int i;
+
+ /* Call atexit() functions */
+ for (i=atexit_count-1; i>=0; --i) {
+ (*atexit_func[i])();
+ }
+ atexit_count = 0;
+
+ /* Free exception ID */
+ if (PJ_NO_MEMORY_EXCEPTION != -1) {
+ pj_exception_id_free(PJ_NO_MEMORY_EXCEPTION);
+ PJ_NO_MEMORY_EXCEPTION = -1;
+ }
+
+#if PJ_HAS_THREADS
+ /* Destroy PJLIB critical section */
+ pj_mutex_destroy(&critical_section);
+
+ /* Free PJLIB TLS */
+ if (thread_tls_id != -1) {
+ pj_thread_local_free(thread_tls_id);
+ thread_tls_id = -1;
+ }
+#endif
+}
+
+
+/*
* pj_getpid(void)
*/
PJ_DEF(pj_uint32_t) pj_getpid(void)
diff --git a/pjlib/src/pj/os_core_win32.c b/pjlib/src/pj/os_core_win32.c
index 27091cc6..ea2c8d94 100644
--- a/pjlib/src/pj/os_core_win32.c
+++ b/pjlib/src/pj/os_core_win32.c
@@ -108,9 +108,10 @@ struct pj_atomic_t
* Static global variables.
*/
static pj_thread_desc main_thread;
-static long thread_tls_id;
+static long thread_tls_id = -1;
static pj_mutex_t critical_section_mutex;
-
+static unsigned atexit_count;
+static void (*atexit_func[32])(void);
/*
* Some static prototypes.
@@ -177,6 +178,52 @@ PJ_DEF(pj_status_t) pj_init(void)
}
/*
+ * pj_atexit()
+ */
+PJ_DEF(pj_status_t) pj_atexit(void (*func)(void))
+{
+ if (atexit_count >= PJ_ARRAY_SIZE(atexit_func))
+ return PJ_ETOOMANY;
+
+ atexit_func[atexit_count++] = func;
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * pj_shutdown(void)
+ */
+PJ_DEF(void) pj_shutdown()
+{
+ int i;
+
+ /* Call atexit() functions */
+ for (i=atexit_count-1; i>=0; --i) {
+ (*atexit_func[i])();
+ }
+ atexit_count = 0;
+
+ /* Free exception ID */
+ if (PJ_NO_MEMORY_EXCEPTION != -1) {
+ pj_exception_id_free(PJ_NO_MEMORY_EXCEPTION);
+ PJ_NO_MEMORY_EXCEPTION = -1;
+ }
+
+ /* Destroy PJLIB critical section */
+ pj_mutex_destroy(&critical_section_mutex);
+
+ /* Free PJLIB TLS */
+ if (thread_tls_id != -1) {
+ pj_thread_local_free(thread_tls_id);
+ thread_tls_id = -1;
+ }
+
+ /* Shutdown Winsock */
+ WSACleanup();
+}
+
+
+/*
* pj_getpid(void)
*/
PJ_DEF(pj_uint32_t) pj_getpid(void)
diff --git a/pjlib/src/pj/pool_buf.c b/pjlib/src/pj/pool_buf.c
index 0da6c5e1..44115f3a 100644
--- a/pjlib/src/pj/pool_buf.c
+++ b/pjlib/src/pj/pool_buf.c
@@ -29,11 +29,21 @@ struct creation_param
};
static int is_initialized;
-static long tls;
+static long tls = -1;
static void* stack_alloc(pj_pool_factory *factory, pj_size_t size);
-static pj_status_t initialize()
+static void pool_buf_cleanup(void)
{
+ if (tls != -1) {
+ pj_thread_local_free(tls);
+ tls = -1;
+ }
+}
+
+static pj_status_t pool_buf_initialize()
+{
+ pj_atexit(&pool_buf_cleanup);
+
stack_based_factory.policy.block_alloc = &stack_alloc;
return pj_thread_local_alloc(&tls);
}
@@ -64,7 +74,7 @@ PJ_DEF(pj_pool_t*) pj_pool_create_on_buf(const char *name,
PJ_ASSERT_RETURN(buf && size, NULL);
if (!is_initialized) {
- if (initialize() != PJ_SUCCESS)
+ if (pool_buf_initialize() != PJ_SUCCESS)
return NULL;
is_initialized = 1;
}
diff --git a/pjsip-apps/src/samples/aectest.c b/pjsip-apps/src/samples/aectest.c
index 85250024..5f150682 100644
--- a/pjsip-apps/src/samples/aectest.c
+++ b/pjsip-apps/src/samples/aectest.c
@@ -210,6 +210,8 @@ int main(int argc, char *argv[])
/* Destroy pool factory */
pj_caching_pool_destroy( &cp );
+ /* Shutdown PJLIB */
+ pj_shutdown();
/* Done. */
return 0;
diff --git a/pjsip-apps/src/samples/confsample.c b/pjsip-apps/src/samples/confsample.c
index c37db4a7..2a943a2c 100644
--- a/pjsip-apps/src/samples/confsample.c
+++ b/pjsip-apps/src/samples/confsample.c
@@ -460,6 +460,8 @@ on_quit:
/* Destroy pool factory */
pj_caching_pool_destroy( &cp );
+ /* Shutdown PJLIB */
+ pj_shutdown();
/* Done. */
return 0;
diff --git a/pjsip-apps/src/samples/level.c b/pjsip-apps/src/samples/level.c
index 278ad7a1..27b4dda3 100644
--- a/pjsip-apps/src/samples/level.c
+++ b/pjsip-apps/src/samples/level.c
@@ -155,6 +155,9 @@ int main(int argc, char *argv[])
/* Destroy pool factory */
pj_caching_pool_destroy( &cp );
+ /* Shutdown PJLIB */
+ pj_shutdown();
+
/* Done. */
return 0;
diff --git a/pjsip-apps/src/samples/pjsip-perf.c b/pjsip-apps/src/samples/pjsip-perf.c
index e9d5f2f5..0f5dab00 100644
--- a/pjsip-apps/src/samples/pjsip-perf.c
+++ b/pjsip-apps/src/samples/pjsip-perf.c
@@ -894,6 +894,9 @@ static void destroy_app()
app.cp.peak_used_size / 1000000));
pj_caching_pool_destroy(&app.cp);
}
+
+ /* Shutdown PJLIB */
+ pj_shutdown();
}
diff --git a/pjsip-apps/src/samples/playfile.c b/pjsip-apps/src/samples/playfile.c
index 387f0776..c267cd8d 100644
--- a/pjsip-apps/src/samples/playfile.c
+++ b/pjsip-apps/src/samples/playfile.c
@@ -195,6 +195,9 @@ int main(int argc, char *argv[])
/* Destroy pool factory */
pj_caching_pool_destroy( &cp );
+ /* Shutdown PJLIB */
+ pj_shutdown();
+
/* Done. */
return 0;
diff --git a/pjsip-apps/src/samples/playsine.c b/pjsip-apps/src/samples/playsine.c
index 4fad85b6..a9a37131 100644
--- a/pjsip-apps/src/samples/playsine.c
+++ b/pjsip-apps/src/samples/playsine.c
@@ -300,6 +300,9 @@ int main(int argc, char *argv[])
/* Destroy pool factory */
pj_caching_pool_destroy( &cp );
+ /* Shutdown PJLIB */
+ pj_shutdown();
+
/* Done. */
return 0;
diff --git a/pjsip-apps/src/samples/recfile.c b/pjsip-apps/src/samples/recfile.c
index 6c197f35..745aa52f 100644
--- a/pjsip-apps/src/samples/recfile.c
+++ b/pjsip-apps/src/samples/recfile.c
@@ -190,6 +190,9 @@ int main(int argc, char *argv[])
/* Destroy pool factory */
pj_caching_pool_destroy( &cp );
+ /* Shutdown PJLIB */
+ pj_shutdown();
+
/* Done. */
return 0;
diff --git a/pjsip-apps/src/samples/resampleplay.c b/pjsip-apps/src/samples/resampleplay.c
index e8d7aa26..396b2674 100644
--- a/pjsip-apps/src/samples/resampleplay.c
+++ b/pjsip-apps/src/samples/resampleplay.c
@@ -216,6 +216,9 @@ int main(int argc, char *argv[])
/* Destroy pool factory */
pj_caching_pool_destroy( &cp );
+ /* Shutdown PJLIB */
+ pj_shutdown();
+
/* Done. */
return 0;
diff --git a/pjsip-apps/src/samples/siprtp.c b/pjsip-apps/src/samples/siprtp.c
index 4fc236ed..10d796e7 100644
--- a/pjsip-apps/src/samples/siprtp.c
+++ b/pjsip-apps/src/samples/siprtp.c
@@ -379,6 +379,10 @@ static void destroy_sip()
pjsip_endpt_destroy(app.sip_endpt);
app.sip_endpt = NULL;
}
+
+ /* Shutdown PJLIB */
+ pj_shutdown();
+
}
diff --git a/pjsip-apps/src/samples/sndinfo.c b/pjsip-apps/src/samples/sndinfo.c
index e15a12c5..fd9bf00f 100644
--- a/pjsip-apps/src/samples/sndinfo.c
+++ b/pjsip-apps/src/samples/sndinfo.c
@@ -285,6 +285,9 @@ int main(int argc, char *argv[])
return 1;
}
+ /* Shutdown PJLIB */
+ pj_shutdown();
+
return 0;
}
diff --git a/pjsip-apps/src/samples/streamutil.c b/pjsip-apps/src/samples/streamutil.c
index 89b0c93a..ed615eb6 100644
--- a/pjsip-apps/src/samples/streamutil.c
+++ b/pjsip-apps/src/samples/streamutil.c
@@ -517,6 +517,9 @@ on_exit:
/* Destroy pool factory */
pj_caching_pool_destroy( &cp );
+ /* Shutdown PJLIB */
+ pj_shutdown();
+
return (status == PJ_SUCCESS) ? 0 : 1;
}
diff --git a/pjsip-apps/src/samples/tonegen.c b/pjsip-apps/src/samples/tonegen.c
index a703a7bb..27ea6318 100644
--- a/pjsip-apps/src/samples/tonegen.c
+++ b/pjsip-apps/src/samples/tonegen.c
@@ -146,6 +146,9 @@ int main()
/* Destroy pool factory */
pj_caching_pool_destroy( &cp );
+ /* Shutdown PJLIB */
+ pj_shutdown();
+
/* Done. */
return 0;
diff --git a/pjsip/src/pjsip/sip_endpoint.c b/pjsip/src/pjsip/sip_endpoint.c
index 2d61e6b9..5586d305 100644
--- a/pjsip/src/pjsip/sip_endpoint.c
+++ b/pjsip/src/pjsip/sip_endpoint.c
@@ -581,6 +581,9 @@ PJ_DEF(void) pjsip_endpt_destroy(pjsip_endpoint *endpt)
/* Delete endpoint mutex. */
pj_mutex_destroy(endpt->mutex);
+ /* Delete module's mutex */
+ pj_rwmutex_destroy(endpt->mod_mutex);
+
/* Finally destroy pool. */
pj_pool_release(endpt->pool);
diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c
index faa9b2fe..af742b6f 100644
--- a/pjsip/src/pjsip/sip_transaction.c
+++ b/pjsip/src/pjsip/sip_transaction.c
@@ -674,6 +674,9 @@ static pj_status_t mod_tsx_layer_unload(void)
/* Release pool. */
pjsip_endpt_release_pool(mod_tsx_layer.endpt, mod_tsx_layer.pool);
+ /* Free TLS */
+ pj_thread_local_free(pjsip_tsx_lock_tls_id);
+
/* Mark as unregistered. */
mod_tsx_layer.endpt = NULL;
diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c
index 000d469f..7d9fa3b8 100644
--- a/pjsip/src/pjsua-lib/pjsua_core.c
+++ b/pjsip/src/pjsua-lib/pjsua_core.c
@@ -707,6 +707,9 @@ PJ_DEF(pj_status_t) pjsua_destroy(void)
pjsua_var.log_file = NULL;
}
+ /* Shutdown PJLIB */
+ pj_shutdown();
+
/* Done. */
return PJ_SUCCESS;
}
diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c
index b040ff84..2a8146c4 100644
--- a/pjsip/src/pjsua-lib/pjsua_media.c
+++ b/pjsip/src/pjsua-lib/pjsua_media.c
@@ -474,6 +474,9 @@ pj_status_t pjsua_media_subsys_destroy(void)
pjsua_var.med_endpt = NULL;
}
+ /* Deinitialize sound subsystem */
+ pjmedia_snd_deinit();
+
return PJ_SUCCESS;
}