summaryrefslogtreecommitdiff
path: root/pjlib/src/pj/timer.c
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2013-02-21 11:18:36 +0000
committerBenny Prijono <bennylp@teluu.com>2013-02-21 11:18:36 +0000
commit9b8e0a5afe9cba0fd430e9642630bd465db9aefa (patch)
tree550cd346c99b144a79c76096dc75d6be2dfb3c31 /pjlib/src/pj/timer.c
parent99de12689e7c6b8117ee82ff8e3c17e5ec85418d (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.c114
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) {