Kannel: Open Source WAP and SMS gateway  $Revision: 5037 $
gw-timer.c File Reference
#include <signal.h>
#include "gwlib/gwlib.h"
#include "gw-timer.h"

Go to the source code of this file.

Data Structures

struct  TimerHeap
 
struct  Timerset
 
struct  Timer
 

Typedefs

typedef struct TimerHeap TimerHeap
 

Functions

static void abort_elapsed (Timer *timer)
 
static TimerHeapheap_create (void)
 
static void heap_destroy (TimerHeap *heap)
 
static void heap_delete (TimerHeap *heap, long index)
 
static int heap_adjust (TimerHeap *heap, long index)
 
static void heap_insert (TimerHeap *heap, Timer *timer)
 
static void heap_swap (TimerHeap *heap, long index1, long index2)
 
static void lock (Timerset *set)
 
static void unlock (Timerset *set)
 
static void watch_timers (void *arg)
 
static void elapse_timer (Timer *timer)
 
Timersetgw_timerset_create (void)
 
void gw_timerset_destroy (Timerset *set)
 
Timergw_timer_create (Timerset *set, List *outputlist, void(*callback)(void *))
 
void gw_timer_destroy (Timer *timer)
 
void gw_timer_elapsed_destroy (Timer *timer)
 
void gw_timer_start (Timer *timer, int interval, void *data)
 
void gw_timer_elapsed_start (Timer *timer, int interval, void *data)
 
void gw_timer_stop (Timer *timer)
 
void gw_timer_elapsed_stop (Timer *timer)
 
Listgw_timer_break (Timerset *set)
 
void * gw_timer_data (Timer *timer)
 

Typedef Documentation

typedef struct TimerHeap TimerHeap

Definition at line 87 of file gw-timer.c.

Function Documentation

static void abort_elapsed ( Timer timer)
static

Definition at line 447 of file gw-timer.c.

References Timer::elapsed_data, gwlist_delete_equal(), and Timer::output.

Referenced by gw_timer_break(), gw_timer_start(), and gw_timer_stop().

448 {
449  if (timer->elapsed_data == NULL)
450  return;
451 
452  if (timer->output != NULL)
453  gwlist_delete_equal(timer->output, timer->elapsed_data);
454  timer->elapsed_data = NULL;
455 }
List * output
Definition: gw-timer.c:128
void * elapsed_data
Definition: gw-timer.c:151
long gwlist_delete_equal(List *list, void *item)
Definition: list.c:266
static void elapse_timer ( Timer timer)
static

Definition at line 617 of file gw-timer.c.

References Timer::callback, Timer::data, Timer::elapsed_data, Timer::elapses, gw_assert(), gwlist_produce(), Timer::output, and Timer::timerset.

Referenced by watch_timers().

618 {
619  gw_assert(timer != NULL);
620  gw_assert(timer->timerset != NULL);
621  /* This must be true because abort_elapsed is always called
622  * before a timer is activated. */
623  gw_assert(timer->elapsed_data == NULL);
624 
625  timer->elapsed_data = timer->data;
626  timer->elapses = -1;
627  if (timer->output != NULL)
628  gwlist_produce(timer->output, timer->elapsed_data);
629  if (timer->callback != NULL)
630  timer->callback(timer->elapsed_data);
631 }
void gwlist_produce(List *list, void *item)
Definition: list.c:411
List * output
Definition: gw-timer.c:128
void * data
Definition: gw-timer.c:144
void(* callback)(void *data)
Definition: gw-timer.c:132
void * elapsed_data
Definition: gw-timer.c:151
gw_assert(wtls_machine->packet_to_send!=NULL)
Timerset * timerset
Definition: gw-timer.c:119
long elapses
Definition: gw-timer.c:138
List* gw_timer_break ( Timerset set)

Definition at line 385 of file gw-timer.c.

References abort_elapsed(), Timer::elapses, gw_assert(), gwlist_append(), gwlist_create, Timerset::heap, heap_delete(), Timer::index, TimerHeap::len, lock(), TimerHeap::tab, and unlock().

386 {
387  List *ret = NULL;
388 
389  lock(set);
390 
391  if (set->heap->len == 0) {
392  unlock(set);
393  return NULL;
394  }
395 
396  ret = gwlist_create();
397 
398  /* Stop all timers. */
399  while (set->heap->len > 0) {
400  Timer *timer = set->heap->tab[0];
401 
402  gwlist_append(ret, timer);
403 
404  /*
405  * If the timer is active, make it inactive and remove it from
406  * the heap.
407  */
408  if (timer->elapses > 0) {
409  timer->elapses = -1;
410  gw_assert(set->heap->tab[timer->index] == timer);
411  heap_delete(set->heap, timer->index);
412  }
413 
414  abort_elapsed(timer);
415  }
416 
417  unlock(set);
418 
419  return ret;
420 }
void gwlist_append(List *list, void *item)
Definition: list.c:179
static void abort_elapsed(Timer *timer)
Definition: gw-timer.c:447
Timer ** tab
Definition: gw-timer.c:83
TimerHeap * heap
Definition: gw-timer.c:106
static void lock(Timerset *set)
Definition: gw-timer.c:429
gw_assert(wtls_machine->packet_to_send!=NULL)
long elapses
Definition: gw-timer.c:138
#define gwlist_create()
Definition: list.h:136
long index
Definition: gw-timer.c:157
long len
Definition: gw-timer.c:84
static void unlock(Timerset *set)
Definition: gw-timer.c:435
static void heap_delete(TimerHeap *heap, long index)
Definition: gw-timer.c:486
Definition: list.c:102
Timer* gw_timer_create ( Timerset set,
List outputlist,
void(*)(void *)  callback 
)

Definition at line 211 of file gw-timer.c.

References Timer::callback, Timer::data, Timer::elapsed_data, Timer::elapses, gwlist_add_producer(), Timer::index, Timer::output, and Timer::timerset.

Referenced by url_result_thread().

212 {
213  Timer *t;
214 
215  t = gw_malloc(sizeof(*t));
216  t->timerset = set;
217  t->elapses = -1;
218  t->data = NULL;
219  t->elapsed_data = NULL;
220  t->index = -1;
221  t->output = outputlist;
222  if (t->output != NULL)
223  gwlist_add_producer(outputlist);
224  t->callback = callback;
225 
226  return t;
227 }
List * output
Definition: gw-timer.c:128
void * data
Definition: gw-timer.c:144
void(* callback)(void *data)
Definition: gw-timer.c:132
void * elapsed_data
Definition: gw-timer.c:151
Timerset * timerset
Definition: gw-timer.c:119
long elapses
Definition: gw-timer.c:138
long index
Definition: gw-timer.c:157
void gwlist_add_producer(List *list)
Definition: list.c:383
void* gw_timer_data ( Timer timer)

Definition at line 422 of file gw-timer.c.

References Timer::data, and gw_assert().

423 {
424  gw_assert(timer != NULL);
425 
426  return timer->data;
427 }
void * data
Definition: gw-timer.c:144
gw_assert(wtls_machine->packet_to_send!=NULL)
void gw_timer_destroy ( Timer timer)

Definition at line 229 of file gw-timer.c.

References gw_timer_stop(), gwlist_remove_producer(), and Timer::output.

230 {
231  if (timer == NULL)
232  return;
233 
234  gw_timer_stop(timer);
235  if (timer->output != NULL)
237  gw_free(timer);
238 }
List * output
Definition: gw-timer.c:128
void gw_timer_stop(Timer *timer)
Definition: gw-timer.c:344
void gwlist_remove_producer(List *list)
Definition: list.c:401
void gw_timer_elapsed_destroy ( Timer timer)

Definition at line 240 of file gw-timer.c.

References gw_timer_elapsed_stop(), gwlist_remove_producer(), and Timer::output.

Referenced by http_queue_thread().

241 {
242  if (timer == NULL)
243  return;
244 
245  gw_timer_elapsed_stop(timer);
246  if (timer->output != NULL)
248  gw_free(timer);
249 }
List * output
Definition: gw-timer.c:128
void gw_timer_elapsed_stop(Timer *timer)
Definition: gw-timer.c:364
void gwlist_remove_producer(List *list)
Definition: list.c:401
void gw_timer_elapsed_start ( Timer timer,
int  interval,
void *  data 
)

Definition at line 297 of file gw-timer.c.

References Timer::data, Timer::elapsed_data, Timer::elapses, gw_assert(), gwthread_wakeup(), Timerset::heap, heap_adjust(), heap_insert(), Timer::index, interval, lock(), TimerHeap::tab, Timerset::thread, Timer::timerset, and unlock().

Referenced by url_result_thread().

298 {
299  int wakeup = 0;
300 
301  gw_assert(timer != NULL);
302 
303  if (timer == NULL)
304  return;
305 
306  lock(timer->timerset);
307 
308  /* Convert to absolute time */
309  interval += time(NULL);
310 
311  if (timer->elapses > 0) {
312  /* Resetting an existing timer. Move it to its new
313  * position in the heap. */
314  if (interval < timer->elapses && timer->index == 0)
315  wakeup = 1;
316  timer->elapses = interval;
317  gw_assert(timer->index >= 0);
318  gw_assert(timer->timerset->heap->tab[timer->index] == timer);
319  wakeup |= heap_adjust(timer->timerset->heap, timer->index);
320  } else {
321  /* Setting a new timer, or resetting an elapsed one.
322  * There should be no further elapse event on the
323  * output list here. */
324  /* abort_elapsed(timer); */
325  timer->elapsed_data = NULL;
326 
327  /* Then activate the timer. */
328  timer->elapses = interval;
329  gw_assert(timer->index < 0);
330  heap_insert(timer->timerset->heap, timer);
331  wakeup = timer->index == 0; /* Do we have a new top? */
332  }
333 
334  if (data != NULL) {
335  timer->data = data;
336  }
337 
338  unlock(timer->timerset);
339 
340  if (wakeup)
342 }
Timer ** tab
Definition: gw-timer.c:83
void * data
Definition: gw-timer.c:144
TimerHeap * heap
Definition: gw-timer.c:106
static void heap_insert(TimerHeap *heap, Timer *timer)
Definition: gw-timer.c:506
static void lock(Timerset *set)
Definition: gw-timer.c:429
void * elapsed_data
Definition: gw-timer.c:151
gw_assert(wtls_machine->packet_to_send!=NULL)
Timerset * timerset
Definition: gw-timer.c:119
double interval
Definition: fakewap.c:234
long thread
Definition: gw-timer.c:111
long elapses
Definition: gw-timer.c:138
void gwthread_wakeup(long thread)
long index
Definition: gw-timer.c:157
static void unlock(Timerset *set)
Definition: gw-timer.c:435
static int heap_adjust(TimerHeap *heap, long index)
Definition: gw-timer.c:549
void gw_timer_elapsed_stop ( Timer timer)

Definition at line 364 of file gw-timer.c.

References Timer::elapsed_data, Timer::elapses, gw_assert(), Timerset::heap, heap_delete(), Timer::index, lock(), TimerHeap::tab, Timer::timerset, and unlock().

Referenced by gw_timer_elapsed_destroy().

365 {
366  gw_assert(timer != NULL);
367  lock(timer->timerset);
368 
369  /*
370  * If the timer is active, make it inactive and remove it from
371  * the heap.
372  */
373  if (timer->elapses > 0) {
374  timer->elapses = -1;
375  gw_assert(timer->timerset->heap->tab[timer->index] == timer);
376  heap_delete(timer->timerset->heap, timer->index);
377  }
378 
379  /* abort_elapsed(timer); */
380  timer->elapsed_data = NULL;
381 
382  unlock(timer->timerset);
383 }
Timer ** tab
Definition: gw-timer.c:83
TimerHeap * heap
Definition: gw-timer.c:106
static void lock(Timerset *set)
Definition: gw-timer.c:429
void * elapsed_data
Definition: gw-timer.c:151
gw_assert(wtls_machine->packet_to_send!=NULL)
Timerset * timerset
Definition: gw-timer.c:119
long elapses
Definition: gw-timer.c:138
long index
Definition: gw-timer.c:157
static void unlock(Timerset *set)
Definition: gw-timer.c:435
static void heap_delete(TimerHeap *heap, long index)
Definition: gw-timer.c:486
void gw_timer_start ( Timer timer,
int  interval,
void *  data 
)

Definition at line 251 of file gw-timer.c.

References abort_elapsed(), Timer::data, Timer::elapses, gw_assert(), gwthread_wakeup(), Timerset::heap, heap_adjust(), heap_insert(), Timer::index, interval, lock(), TimerHeap::tab, Timerset::thread, Timer::timerset, and unlock().

252 {
253  int wakeup = 0;
254 
255  gw_assert(timer != NULL);
256 
257  if (timer == NULL)
258  return;
259 
260  lock(timer->timerset);
261 
262  /* Convert to absolute time */
263  interval += time(NULL);
264 
265  if (timer->elapses > 0) {
266  /* Resetting an existing timer. Move it to its new
267  * position in the heap. */
268  if (interval < timer->elapses && timer->index == 0)
269  wakeup = 1;
270  timer->elapses = interval;
271  gw_assert(timer->index >= 0);
272  gw_assert(timer->timerset->heap->tab[timer->index] == timer);
273  wakeup |= heap_adjust(timer->timerset->heap, timer->index);
274  } else {
275  /* Setting a new timer, or resetting an elapsed one.
276  * First deal with a possible elapse event that may
277  * still be on the output list. */
278  abort_elapsed(timer);
279 
280  /* Then activate the timer. */
281  timer->elapses = interval;
282  gw_assert(timer->index < 0);
283  heap_insert(timer->timerset->heap, timer);
284  wakeup = timer->index == 0; /* Do we have a new top? */
285  }
286 
287  if (data != NULL) {
288  timer->data = data;
289  }
290 
291  unlock(timer->timerset);
292 
293  if (wakeup)
295 }
static void abort_elapsed(Timer *timer)
Definition: gw-timer.c:447
Timer ** tab
Definition: gw-timer.c:83
void * data
Definition: gw-timer.c:144
TimerHeap * heap
Definition: gw-timer.c:106
static void heap_insert(TimerHeap *heap, Timer *timer)
Definition: gw-timer.c:506
static void lock(Timerset *set)
Definition: gw-timer.c:429
gw_assert(wtls_machine->packet_to_send!=NULL)
Timerset * timerset
Definition: gw-timer.c:119
double interval
Definition: fakewap.c:234
long thread
Definition: gw-timer.c:111
long elapses
Definition: gw-timer.c:138
void gwthread_wakeup(long thread)
long index
Definition: gw-timer.c:157
static void unlock(Timerset *set)
Definition: gw-timer.c:435
static int heap_adjust(TimerHeap *heap, long index)
Definition: gw-timer.c:549
void gw_timer_stop ( Timer timer)

Definition at line 344 of file gw-timer.c.

References abort_elapsed(), Timer::elapses, gw_assert(), Timerset::heap, heap_delete(), Timer::index, lock(), TimerHeap::tab, Timer::timerset, and unlock().

Referenced by gw_timer_destroy(), and gw_timerset_destroy().

345 {
346  gw_assert(timer != NULL);
347  lock(timer->timerset);
348 
349  /*
350  * If the timer is active, make it inactive and remove it from
351  * the heap.
352  */
353  if (timer->elapses > 0) {
354  timer->elapses = -1;
355  gw_assert(timer->timerset->heap->tab[timer->index] == timer);
356  heap_delete(timer->timerset->heap, timer->index);
357  }
358 
359  abort_elapsed(timer);
360 
361  unlock(timer->timerset);
362 }
static void abort_elapsed(Timer *timer)
Definition: gw-timer.c:447
Timer ** tab
Definition: gw-timer.c:83
TimerHeap * heap
Definition: gw-timer.c:106
static void lock(Timerset *set)
Definition: gw-timer.c:429
gw_assert(wtls_machine->packet_to_send!=NULL)
Timerset * timerset
Definition: gw-timer.c:119
long elapses
Definition: gw-timer.c:138
long index
Definition: gw-timer.c:157
static void unlock(Timerset *set)
Definition: gw-timer.c:435
static void heap_delete(TimerHeap *heap, long index)
Definition: gw-timer.c:486
Timerset* gw_timerset_create ( void  )

Definition at line 177 of file gw-timer.c.

References gwthread_create, Timerset::heap, heap_create(), Timerset::mutex, mutex_create, Timerset::stopping, Timerset::thread, and watch_timers().

Referenced by main().

178 {
179  Timerset *set;
180 
181  set = gw_malloc(sizeof(Timerset));
182  set->mutex = mutex_create();
183  set->heap = heap_create();
184  set->stopping = 0;
185  set->thread = gwthread_create(watch_timers, set);
186 
187  return set;
188 }
volatile sig_atomic_t stopping
Definition: gw-timer.c:94
#define mutex_create()
Definition: thread.h:96
TimerHeap * heap
Definition: gw-timer.c:106
static void watch_timers(void *arg)
Definition: gw-timer.c:636
#define gwthread_create(func, arg)
Definition: gwthread.h:90
long thread
Definition: gw-timer.c:111
static TimerHeap * heap_create(void)
Definition: gw-timer.c:460
Mutex * mutex
Definition: gw-timer.c:101
void gw_timerset_destroy ( Timerset set)

Definition at line 190 of file gw-timer.c.

References gw_timer_stop(), gwthread_join(), gwthread_wakeup(), Timerset::heap, heap_destroy(), TimerHeap::len, Timerset::mutex, mutex_destroy(), Timerset::stopping, TimerHeap::tab, and Timerset::thread.

Referenced by main().

191 {
192  if (set == NULL)
193  return;
194 
195  /* Stop all timers. */
196  while (set->heap->len > 0)
197  gw_timer_stop(set->heap->tab[0]);
198 
199  /* Kill timer thread */
200  set->stopping = 1;
201  gwthread_wakeup(set->thread);
202  gwthread_join(set->thread);
203 
204  /* Free resources */
205  heap_destroy(set->heap);
206  mutex_destroy(set->mutex);
207  gw_free(set);
208 }
volatile sig_atomic_t stopping
Definition: gw-timer.c:94
void gwthread_join(long thread)
static void heap_destroy(TimerHeap *heap)
Definition: gw-timer.c:472
Timer ** tab
Definition: gw-timer.c:83
TimerHeap * heap
Definition: gw-timer.c:106
void gw_timer_stop(Timer *timer)
Definition: gw-timer.c:344
void mutex_destroy(Mutex *mutex)
Definition: thread.c:97
long thread
Definition: gw-timer.c:111
void gwthread_wakeup(long thread)
long len
Definition: gw-timer.c:84
Mutex * mutex
Definition: gw-timer.c:101
static int heap_adjust ( TimerHeap heap,
long  index 
)
static

Definition at line 549 of file gw-timer.c.

References Timer::elapses, gw_assert(), heap_swap(), TimerHeap::len, and TimerHeap::tab.

Referenced by gw_timer_elapsed_start(), gw_timer_start(), heap_delete(), and heap_insert().

550 {
551  Timer *t;
552  Timer *parent;
553  long child_index;
554 
555  /*
556  * We can assume that the heap was fine before this element's
557  * elapse time was changed. There are three cases to deal
558  * with:
559  * - Element's new elapse time is too small; it should be
560  * moved toward the top.
561  * - Element's new elapse time is too large; it should be
562  * moved toward the bottom.
563  * - Element's new elapse time still fits here, we don't
564  * have to do anything.
565  */
566 
567  gw_assert(index >= 0);
568  gw_assert(index < heap->len);
569 
570  /* Move to top? */
571  t = heap->tab[index];
572  parent = heap->tab[index / 2];
573  if (t->elapses < parent->elapses) {
574  /* This will automatically terminate when it reaches
575  * the top, because in that t == parent. */
576  do {
577  heap_swap(heap, index, index / 2);
578  index = index / 2;
579  parent = heap->tab[index / 2];
580  } while (t->elapses < parent->elapses);
581  /* We're done. Return 1 if we changed the top. */
582  return index == 0;
583  }
584 
585  /* Move to bottom? */
586  for (; ; ) {
587  child_index = index * 2;
588  if (child_index >= heap->len)
589  return 0; /* Already at bottom */
590  if (child_index == heap->len - 1) {
591  /* Only one child */
592  if (heap->tab[child_index]->elapses < t->elapses)
593  heap_swap(heap, index, child_index);
594  break;
595  }
596 
597  /* Find out which child elapses first */
598  if (heap->tab[child_index + 1]->elapses <
599  heap->tab[child_index]->elapses) {
600  child_index++;
601  }
602 
603  if (heap->tab[child_index]->elapses < t->elapses) {
604  heap_swap(heap, index, child_index);
605  index = child_index;
606  } else {
607  break;
608  }
609  }
610 
611  return 0;
612 }
Timer ** tab
Definition: gw-timer.c:83
gw_assert(wtls_machine->packet_to_send!=NULL)
static void heap_swap(TimerHeap *heap, long index1, long index2)
Definition: gw-timer.c:523
long elapses
Definition: gw-timer.c:138
long len
Definition: gw-timer.c:84
static TimerHeap * heap_create ( void  )
static

Definition at line 460 of file gw-timer.c.

References TimerHeap::len, TimerHeap::size, and TimerHeap::tab.

Referenced by gw_timerset_create().

461 {
462  TimerHeap *heap;
463 
464  heap = gw_malloc(sizeof(*heap));
465  heap->tab = gw_malloc(sizeof(heap->tab[0]));
466  heap->size = 1;
467  heap->len = 0;
468 
469  return heap;
470 }
long size
Definition: gw-timer.c:85
Timer ** tab
Definition: gw-timer.c:83
long len
Definition: gw-timer.c:84
static void heap_delete ( TimerHeap heap,
long  index 
)
static

Definition at line 486 of file gw-timer.c.

References gw_assert(), heap_adjust(), heap_swap(), Timer::index, TimerHeap::len, and TimerHeap::tab.

Referenced by gw_timer_break(), gw_timer_elapsed_stop(), gw_timer_stop(), and watch_timers().

487 {
488  long last;
489 
490  gw_assert(index >= 0);
491  gw_assert(index < heap->len);
492  gw_assert(heap->tab[index]->index == index);
493 
494  last = heap->len - 1;
495  heap_swap(heap, index, last);
496  heap->tab[last]->index = -1;
497  heap->len--;
498  if (index != last)
499  heap_adjust(heap, index);
500 }
Timer ** tab
Definition: gw-timer.c:83
gw_assert(wtls_machine->packet_to_send!=NULL)
static void heap_swap(TimerHeap *heap, long index1, long index2)
Definition: gw-timer.c:523
long index
Definition: gw-timer.c:157
long len
Definition: gw-timer.c:84
static int heap_adjust(TimerHeap *heap, long index)
Definition: gw-timer.c:549
static void heap_destroy ( TimerHeap heap)
static

Definition at line 472 of file gw-timer.c.

References TimerHeap::tab.

Referenced by gw_timerset_destroy().

473 {
474  if (heap == NULL)
475  return;
476 
477  gw_free(heap->tab);
478  gw_free(heap);
479 }
Timer ** tab
Definition: gw-timer.c:83
static void heap_insert ( TimerHeap heap,
Timer timer 
)
static

Definition at line 506 of file gw-timer.c.

References heap_adjust(), Timer::index, TimerHeap::len, TimerHeap::size, and TimerHeap::tab.

Referenced by gw_timer_elapsed_start(), and gw_timer_start().

507 {
508  heap->len++;
509  if (heap->len > heap->size) {
510  heap->tab = gw_realloc(heap->tab,
511  heap->len * sizeof(heap->tab[0]));
512  heap->size = heap->len;
513  }
514  heap->tab[heap->len - 1] = timer;
515  timer->index = heap->len - 1;
516  heap_adjust(heap, timer->index);
517 }
long size
Definition: gw-timer.c:85
Timer ** tab
Definition: gw-timer.c:83
long index
Definition: gw-timer.c:157
long len
Definition: gw-timer.c:84
static int heap_adjust(TimerHeap *heap, long index)
Definition: gw-timer.c:549
static void heap_swap ( TimerHeap heap,
long  index1,
long  index2 
)
static

Definition at line 523 of file gw-timer.c.

References gw_assert(), Timer::index, and TimerHeap::tab.

Referenced by heap_adjust(), and heap_delete().

524 {
525  Timer *t;
526 
527  gw_assert(index1 >= 0);
528  gw_assert(index1 < heap->len);
529  gw_assert(index2 >= 0);
530  gw_assert(index2 < heap->len);
531 
532  if (index1 == index2)
533  return;
534 
535  t = heap->tab[index1];
536  heap->tab[index1] = heap->tab[index2];
537  heap->tab[index2] = t;
538  heap->tab[index1]->index = index1;
539  heap->tab[index2]->index = index2;
540 }
Timer ** tab
Definition: gw-timer.c:83
gw_assert(wtls_machine->packet_to_send!=NULL)
long index
Definition: gw-timer.c:157
static void lock ( Timerset set)
static

Definition at line 429 of file gw-timer.c.

References gw_assert(), Timerset::mutex, and mutex_lock.

Referenced by gw_timer_break(), gw_timer_elapsed_start(), gw_timer_elapsed_stop(), gw_timer_start(), gw_timer_stop(), and watch_timers().

430 {
431  gw_assert(set != NULL);
432  mutex_lock(set->mutex);
433 }
gw_assert(wtls_machine->packet_to_send!=NULL)
Mutex * mutex
Definition: gw-timer.c:101
#define mutex_lock(m)
Definition: thread.h:130
static void unlock ( Timerset set)
static

Definition at line 435 of file gw-timer.c.

References gw_assert(), Timerset::mutex, and mutex_unlock.

Referenced by gw_timer_break(), gw_timer_elapsed_start(), gw_timer_elapsed_stop(), gw_timer_start(), gw_timer_stop(), and watch_timers().

436 {
437  gw_assert(set != NULL);
438  mutex_unlock(set->mutex);
439 }
#define mutex_unlock(m)
Definition: thread.h:136
gw_assert(wtls_machine->packet_to_send!=NULL)
Mutex * mutex
Definition: gw-timer.c:101
static void watch_timers ( void *  arg)
static

Definition at line 636 of file gw-timer.c.

References elapse_timer(), Timer::elapses, gwthread_sleep(), Timerset::heap, heap_delete(), TimerHeap::len, lock(), Timerset::stopping, TimerHeap::tab, and unlock().

Referenced by gw_timerset_create().

637 {
638  Timerset *set;
639  long top_time;
640  long now;
641 
642  set = arg;
643 
644  while (!set->stopping) {
645  lock(set);
646 
647  now = time(NULL);
648 
649  while (set->heap->len > 0 && set->heap->tab[0]->elapses <= now) {
650  Timer *timer = set->heap->tab[0];
651  heap_delete(set->heap, 0);
652  elapse_timer(timer);
653  }
654 
655  /*
656  * Now sleep until the next timer elapses. If there isn't one,
657  * then just sleep very long. We will get woken up if the
658  * top of the heap changes before we wake.
659  */
660 
661  if (set->heap->len == 0) {
662  unlock(set);
663  gwthread_sleep(1000000.0);
664  } else {
665  top_time = set->heap->tab[0]->elapses;
666  unlock(set);
667  gwthread_sleep(top_time - now);
668  }
669  }
670 }
volatile sig_atomic_t stopping
Definition: gw-timer.c:94
Timer ** tab
Definition: gw-timer.c:83
TimerHeap * heap
Definition: gw-timer.c:106
static void lock(Timerset *set)
Definition: gw-timer.c:429
static void elapse_timer(Timer *timer)
Definition: gw-timer.c:617
void gwthread_sleep(double seconds)
long elapses
Definition: gw-timer.c:138
long len
Definition: gw-timer.c:84
static void unlock(Timerset *set)
Definition: gw-timer.c:435
static void heap_delete(TimerHeap *heap, long index)
Definition: gw-timer.c:486
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.