heartbeat.c
上传用户:gzpyjq
上传日期:2013-01-31
资源大小:1852k
文件大小:3k
源码类别:

手机WAP编程

开发平台:

WINDOWS

  1. /*
  2.  * heartbeat.c - thread for sending heartbeat Msgs to bearerbox
  3.  */
  4. #include <signal.h>
  5. #include "gwlib/gwlib.h"
  6. #include "msg.h"
  7. #include "heartbeat.h"
  8. /*
  9.  * Each running heartbeat gets one of these.  They are collected in
  10.  * the heartbeats List.
  11.  */
  12. struct hb_info {
  13.     hb_send_func_t *send_func;
  14.     double freq;
  15.     hb_load_func_t *load_func;
  16.     long thread;
  17.     volatile sig_atomic_t running;
  18. };
  19. /* List of struct hb_info. */
  20. static List *heartbeats;
  21. /*
  22.  * Look for a hb_info in a list, by thread number.
  23.  */
  24. static int find_hb(void *item, void *pattern)
  25. {
  26.     long *threadnrp;
  27.     struct hb_info *info;
  28.     info = item;
  29.     threadnrp = pattern;
  30.     return info->thread == *threadnrp;
  31. }
  32. static void heartbeat_thread(void *arg)
  33. {
  34.     struct hb_info *info;
  35.     time_t last_hb;
  36.     info = arg;
  37.     last_hb = 0;
  38.     while (info->running) {
  39.         Msg *msg;
  40.         gwthread_sleep(info->freq);
  41.         /*
  42.          * Because the sleep can be interrupted, we might end up sending
  43.          * heartbeats faster than the configured heartbeat frequency.
  44.          * This is not bad unless we send them way too fast.  Make sure
  45.          * our frequency is not more than twice the configured one.
  46.          */
  47.         if (difftime(last_hb, time(NULL)) < info->freq / 2)
  48.             continue;
  49.         msg = msg_create(heartbeat);
  50.         msg->heartbeat.load = info->load_func();
  51.         info->send_func(msg);
  52.         last_hb = time(NULL);
  53.     }
  54. }
  55. long heartbeat_start(hb_send_func_t *send_func, double freq,
  56.                      hb_load_func_t *load_func)
  57. {
  58.     struct hb_info *info;
  59.     info = gw_malloc(sizeof(*info));
  60.     info->send_func = send_func;
  61.     info->freq = (freq <= 0 ? DEFAULT_HEARTBEAT : freq);
  62.     info->load_func = load_func;
  63.     info->running = 1;
  64.     info->thread = gwthread_create(heartbeat_thread, info);
  65.     if (info->thread >= 0) {
  66. if (heartbeats == NULL)
  67.     heartbeats = list_create();
  68. list_append(heartbeats, info);
  69.         return info->thread;
  70.     } else {
  71.         gw_free(info);
  72.         return -1;
  73.     }
  74. }
  75. /*
  76.  * function : heartbeat_stop
  77.  * arguments: long hb_thread, the thread number of the heartbeat
  78.  *            that is wished to be stopped.
  79.  *            if hb_thread == ALL_HEARTBEATS then all heartbeats
  80.  *            are stopped.
  81.  * returns  : -
  82.  */
  83. void heartbeat_stop(long hb_thread)
  84. {
  85.     List *matching_info;
  86.     struct hb_info *info;
  87.     if (hb_thread == ALL_HEARTBEATS) {
  88.         while (NULL != (info = list_extract_first(heartbeats))) {
  89.             gw_assert(info);
  90.             info->running = 0;
  91.             gwthread_wakeup(info->thread);
  92.             gwthread_join(info->thread);
  93.             gw_free(info);
  94.         }
  95.     } else {
  96.         matching_info = list_extract_matching(heartbeats, &hb_thread, find_hb);
  97.         if (matching_info == NULL) {
  98.             warning(0, "Could not stop heartbeat %ld: not found.", hb_thread);
  99.     return;
  100.         }
  101.         gw_assert(list_len(matching_info) == 1);
  102.         info = list_extract_first(matching_info);
  103.         list_destroy(matching_info, NULL);
  104.      
  105.         info->running = 0;
  106.         gwthread_wakeup(hb_thread);
  107.         gwthread_join(hb_thread);
  108.         gw_free(info);
  109.     }
  110.     if (list_len(heartbeats) == 0) {
  111.         list_destroy(heartbeats, NULL);
  112.         heartbeats = NULL;
  113.     }
  114. }