summaryrefslogtreecommitdiff
path: root/pjlib/src/pj/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'pjlib/src/pj/timer.c')
-rw-r--r--pjlib/src/pj/timer.c119
1 files changed, 107 insertions, 12 deletions
diff --git a/pjlib/src/pj/timer.c b/pjlib/src/pj/timer.c
index e78cba3..7951955 100644
--- a/pjlib/src/pj/timer.c
+++ b/pjlib/src/pj/timer.c
@@ -1,4 +1,4 @@
-/* $Id: timer.c 4154 2012-06-05 10:41:17Z bennylp $ */
+/* $Id: timer.c 4359 2013-02-21 11:18:36Z bennylp $ */
/*
* The PJLIB's timer heap is based (or more correctly, copied and modied)
* from ACE library by Douglas C. Schmidt. ACE is an excellent OO framework
@@ -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 )
{
@@ -512,25 +594,38 @@ PJ_DEF(unsigned) pj_timer_heap_poll( pj_timer_heap_t *ht,
PJ_ASSERT_RETURN(ht, 0);
+ lock_timer_heap(ht);
if (!ht->cur_size && next_delay) {
next_delay->sec = next_delay->msec = PJ_MAXINT32;
+ unlock_timer_heap(ht);
return 0;
}
count = 0;
pj_gettickcount(&now);
- lock_timer_heap(ht);
while ( ht->cur_size &&
PJ_TIME_VAL_LTE(ht->heap[0]->_timer_value, now) &&
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) {