summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-09-12 23:49:16 +0000
committerBenny Prijono <bennylp@teluu.com>2006-09-12 23:49:16 +0000
commit24d82c099af823ce401cc116a6ba3242ea922352 (patch)
tree8239812be20f7bd1fdf5f50b0cb097e7e430c3c3
parentbbb158d5163649c340e733c22cb883f28bb01557 (diff)
Fixed mutex leaking in Linux: pj_mutex_destroy() will fail to destroy the mutex if the mutex is currently being held. Unfortunately it is quite common in the libraries to acquire the mutex first before destroying it, causing mutexes to leak. The solution is to retry unlocking/destroying the mutex several times (currently 4) while pthread_mutex_destroy() returns EBUSY
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@708 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjlib/src/pj/os_core_unix.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/pjlib/src/pj/os_core_unix.c b/pjlib/src/pj/os_core_unix.c
index 2b640cbc..03aa8f86 100644
--- a/pjlib/src/pj/os_core_unix.c
+++ b/pjlib/src/pj/os_core_unix.c
@@ -1101,7 +1101,9 @@ PJ_DEF(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex)
*/
PJ_DEF(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex)
{
+ enum { RETRY = 4 };
int status;
+ unsigned retry;
PJ_CHECK_STACK();
PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
@@ -1109,11 +1111,21 @@ PJ_DEF(pj_status_t) pj_mutex_destroy(pj_mutex_t *mutex)
#if PJ_HAS_THREADS
PJ_LOG(6,(mutex->obj_name, "Mutex destroyed by thread %s",
pj_thread_this()->obj_name));
- status = pthread_mutex_destroy( &mutex->mutex );
+
+ for (retry=0; retry<RETRY; ++retry) {
+ status = pthread_mutex_destroy( &mutex->mutex );
+ if (status == PJ_SUCCESS)
+ break;
+ else if (retry<RETRY-1 && status == EBUSY)
+ pthread_mutex_unlock(&mutex->mutex);
+ }
+
if (status == 0)
return PJ_SUCCESS;
- else
+ else {
+ pj_assert(!"Error destroying pthread_mutex");
return PJ_RETURN_OS_ERROR(status);
+ }
#else
pj_assert( mutex == (pj_mutex_t*)1 );
status = PJ_SUCCESS;