summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2013-03-01 03:46:45 +0000
committerNanang Izzuddin <nanang@teluu.com>2013-03-01 03:46:45 +0000
commit0ea79636890aa26ad47dd06962cb1e668e3cfc30 (patch)
treecfddf03a07957f9f2fa62398a32eb7d924809844
parent4a841f08f9eda7a9649e15f8ce2afd2d5ff9b9b4 (diff)
Re 1394 and re #1531: backported to 1.x
git-svn-id: http://svn.pjsip.org/repos/pjproject/branches/1.x@4410 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjlib/src/pj/os_core_win32.c3
-rw-r--r--pjmedia/src/pjmedia/clock_thread.c47
2 files changed, 36 insertions, 14 deletions
diff --git a/pjlib/src/pj/os_core_win32.c b/pjlib/src/pj/os_core_win32.c
index 55d7b1b9..5072c4ce 100644
--- a/pjlib/src/pj/os_core_win32.c
+++ b/pjlib/src/pj/os_core_win32.c
@@ -579,6 +579,9 @@ PJ_DEF(pj_status_t) pj_thread_join(pj_thread_t *p)
PJ_CHECK_STACK();
PJ_ASSERT_RETURN(p, PJ_EINVAL);
+ if (p == pj_thread_this())
+ return PJ_ECANCELLED;
+
PJ_LOG(6, (pj_thread_this()->obj_name, "Joining thread %s", p->obj_name));
rc = WaitForSingleObject(rec->hthread, INFINITE);
diff --git a/pjmedia/src/pjmedia/clock_thread.c b/pjmedia/src/pjmedia/clock_thread.c
index 245db00c..33a75d40 100644
--- a/pjmedia/src/pjmedia/clock_thread.c
+++ b/pjmedia/src/pjmedia/clock_thread.c
@@ -31,6 +31,7 @@
struct pjmedia_clock
{
+ pj_pool_t *pool;
pj_timestamp freq;
pj_timestamp interval;
pj_timestamp next_tick;
@@ -70,8 +71,8 @@ PJ_DEF(pj_status_t) pjmedia_clock_create( pj_pool_t *pool,
PJ_EINVAL);
clock = PJ_POOL_ALLOC_T(pool, pjmedia_clock);
+ clock->pool = pj_pool_create(pool->factory, "clock%p", 512, 512, NULL);
-
status = pj_get_timestamp_freq(&clock->freq);
if (status != PJ_SUCCESS)
return status;
@@ -94,16 +95,6 @@ PJ_DEF(pj_status_t) pjmedia_clock_create( pj_pool_t *pool,
if (status != PJ_SUCCESS)
return status;
- if ((clock->options & PJMEDIA_CLOCK_NO_ASYNC) == 0) {
- status = pj_thread_create(pool, "clock", &clock_thread, clock,
- 0, 0, &clock->thread);
- if (status != PJ_SUCCESS) {
- pj_lock_destroy(clock->lock);
- return status;
- }
- }
-
-
*p_clock = clock;
return PJ_SUCCESS;
@@ -127,12 +118,20 @@ PJ_DEF(pj_status_t) pjmedia_clock_start(pjmedia_clock *clock)
if (status != PJ_SUCCESS)
return status;
- pj_lock_acquire(clock->lock);
clock->next_tick.u64 = now.u64 + clock->interval.u64;
clock->running = PJ_TRUE;
- pj_lock_release(clock->lock);
+ clock->quitting = PJ_FALSE;
- return status;
+ if ((clock->options & PJMEDIA_CLOCK_NO_ASYNC) == 0 && !clock->thread) {
+ status = pj_thread_create(clock->pool, "clock", &clock_thread, clock,
+ 0, 0, &clock->thread);
+ if (status != PJ_SUCCESS) {
+ clock->running = PJ_FALSE;
+ return status;
+ }
+ }
+
+ return PJ_SUCCESS;
}
@@ -144,6 +143,17 @@ PJ_DEF(pj_status_t) pjmedia_clock_stop(pjmedia_clock *clock)
PJ_ASSERT_RETURN(clock != NULL, PJ_EINVAL);
clock->running = PJ_FALSE;
+ clock->quitting = PJ_TRUE;
+
+ if (clock->thread) {
+ if (pj_thread_join(clock->thread) == PJ_SUCCESS) {
+ pj_thread_destroy(clock->thread);
+ clock->thread = NULL;
+ pj_pool_reset(clock->pool);
+ } else {
+ clock->quitting = PJ_FALSE;
+ }
+ }
return PJ_SUCCESS;
}
@@ -254,6 +264,10 @@ static int clock_thread(void *arg)
if (clock->cb)
(*clock->cb)(&clock->timestamp, clock->user_data);
+ /* Best effort way to detect if we've been destroyed in the callback */
+ if (clock->quitting)
+ break;
+
/* Increment timestamp */
clock->timestamp.u64 += clock->timestamp_inc;
@@ -288,6 +302,11 @@ PJ_DEF(pj_status_t) pjmedia_clock_destroy(pjmedia_clock *clock)
clock->lock = NULL;
}
+ if (clock->pool) {
+ pj_pool_t *pool = clock->pool;
+ clock->pool = NULL;
+ pj_pool_release(pool);
+ }
return PJ_SUCCESS;
}