diff options
author | Benny Prijono <bennylp@teluu.com> | 2013-02-21 11:18:36 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2013-02-21 11:18:36 +0000 |
commit | 9b8e0a5afe9cba0fd430e9642630bd465db9aefa (patch) | |
tree | 550cd346c99b144a79c76096dc75d6be2dfb3c31 /pjlib/src/pj/timer.c | |
parent | 99de12689e7c6b8117ee82ff8e3c17e5ec85418d (diff) |
Fixed #1616: Implementation of Group lock and other foundation in PJLIB for fixing synchronization issues
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4359 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib/src/pj/timer.c')
-rw-r--r-- | pjlib/src/pj/timer.c | 114 |
1 files changed, 104 insertions, 10 deletions
diff --git a/pjlib/src/pj/timer.c b/pjlib/src/pj/timer.c index 767a261f..47209fbe 100644 --- a/pjlib/src/pj/timer.c +++ b/pjlib/src/pj/timer.c @@ -35,6 +35,7 @@ #include <pj/errno.h> #include <pj/lock.h> #include <pj/log.h> +#include <pj/rand.h> #define THIS_FILE "timer.c" @@ -451,20 +452,27 @@ PJ_DEF(pj_timer_entry*) pj_timer_entry_init( pj_timer_entry *entry, entry->id = id; entry->user_data = user_data; entry->cb = cb; + entry->_grp_lock = NULL; return entry; } #if PJ_TIMER_DEBUG -PJ_DEF(pj_status_t) pj_timer_heap_schedule_dbg( pj_timer_heap_t *ht, - pj_timer_entry *entry, - const pj_time_val *delay, - const char *src_file, - int src_line) +static pj_status_t schedule_w_grp_lock_dbg(pj_timer_heap_t *ht, + pj_timer_entry *entry, + const pj_time_val *delay, + pj_bool_t set_id, + int id_val, + pj_grp_lock_t *grp_lock, + const char *src_file, + int src_line) #else -PJ_DEF(pj_status_t) pj_timer_heap_schedule( pj_timer_heap_t *ht, - pj_timer_entry *entry, - const pj_time_val *delay) +static pj_status_t schedule_w_grp_lock(pj_timer_heap_t *ht, + pj_timer_entry *entry, + const pj_time_val *delay, + pj_bool_t set_id, + int id_val, + pj_grp_lock_t *grp_lock) #endif { pj_status_t status; @@ -485,13 +493,66 @@ PJ_DEF(pj_status_t) pj_timer_heap_schedule( pj_timer_heap_t *ht, lock_timer_heap(ht); status = schedule_entry(ht, entry, &expires); + if (status == PJ_SUCCESS) { + if (set_id) + entry->id = id_val; + entry->_grp_lock = grp_lock; + if (entry->_grp_lock) { + pj_grp_lock_add_ref(entry->_grp_lock); + } + } unlock_timer_heap(ht); return status; } -PJ_DEF(int) pj_timer_heap_cancel( pj_timer_heap_t *ht, - pj_timer_entry *entry) + +#if PJ_TIMER_DEBUG +PJ_DEF(pj_status_t) pj_timer_heap_schedule_dbg( pj_timer_heap_t *ht, + pj_timer_entry *entry, + const pj_time_val *delay, + const char *src_file, + int src_line) +{ + return schedule_w_grp_lock_dbg(ht, entry, delay, PJ_FALSE, 1, NULL, + src_file, src_line); +} + +PJ_DEF(pj_status_t) pj_timer_heap_schedule_w_grp_lock_dbg( + pj_timer_heap_t *ht, + pj_timer_entry *entry, + const pj_time_val *delay, + int id_val, + pj_grp_lock_t *grp_lock, + const char *src_file, + int src_line) +{ + return schedule_w_grp_lock_dbg(ht, entry, delay, PJ_TRUE, id_val, + grp_lock, src_file, src_line); +} + +#else +PJ_DEF(pj_status_t) pj_timer_heap_schedule( pj_timer_heap_t *ht, + pj_timer_entry *entry, + const pj_time_val *delay) +{ + return schedule_w_grp_lock(ht, entry, delay, PJ_FALSE, 1, NULL); +} + +PJ_DEF(pj_status_t) pj_timer_heap_schedule_w_grp_lock(pj_timer_heap_t *ht, + pj_timer_entry *entry, + const pj_time_val *delay, + int id_val, + pj_grp_lock_t *grp_lock) +{ + return schedule_w_grp_lock(ht, entry, delay, PJ_TRUE, id_val, grp_lock); +} +#endif + +static int cancel_timer(pj_timer_heap_t *ht, + pj_timer_entry *entry, + pj_bool_t set_id, + int id_val) { int count; @@ -499,11 +560,32 @@ PJ_DEF(int) pj_timer_heap_cancel( pj_timer_heap_t *ht, lock_timer_heap(ht); count = cancel(ht, entry, 1); + if (set_id) { + entry->id = id_val; + } + if (entry->_grp_lock) { + pj_grp_lock_t *grp_lock = entry->_grp_lock; + entry->_grp_lock = NULL; + pj_grp_lock_dec_ref(grp_lock); + } unlock_timer_heap(ht); return count; } +PJ_DEF(int) pj_timer_heap_cancel( pj_timer_heap_t *ht, + pj_timer_entry *entry) +{ + return cancel_timer(ht, entry, PJ_FALSE, 0); +} + +PJ_DEF(int) pj_timer_heap_cancel_if_active(pj_timer_heap_t *ht, + pj_timer_entry *entry, + int id_val) +{ + return cancel_timer(ht, entry, PJ_TRUE, id_val); +} + PJ_DEF(unsigned) pj_timer_heap_poll( pj_timer_heap_t *ht, pj_time_val *next_delay ) { @@ -527,11 +609,23 @@ PJ_DEF(unsigned) pj_timer_heap_poll( pj_timer_heap_t *ht, count < ht->max_entries_per_poll ) { pj_timer_entry *node = remove_node(ht, 0); + pj_grp_lock_t *grp_lock; + ++count; + grp_lock = node->_grp_lock; + node->_grp_lock = NULL; + unlock_timer_heap(ht); + + PJ_RACE_ME(5); + if (node->cb) (*node->cb)(ht, node); + + if (grp_lock) + pj_grp_lock_dec_ref(grp_lock); + lock_timer_heap(ht); } if (ht->cur_size && next_delay) { |