diff options
author | Nanang Izzuddin <nanang@teluu.com> | 2013-03-01 03:46:45 +0000 |
---|---|---|
committer | Nanang Izzuddin <nanang@teluu.com> | 2013-03-01 03:46:45 +0000 |
commit | 0ea79636890aa26ad47dd06962cb1e668e3cfc30 (patch) | |
tree | cfddf03a07957f9f2fa62398a32eb7d924809844 | |
parent | 4a841f08f9eda7a9649e15f8ce2afd2d5ff9b9b4 (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.c | 3 | ||||
-rw-r--r-- | pjmedia/src/pjmedia/clock_thread.c | 47 |
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; } |