Simplify timer API interface
authorHenning Rogge <hrogge@googlemail.com>
Wed, 29 Feb 2012 17:12:09 +0000 (18:12 +0100)
committerHenning Rogge <hrogge@googlemail.com>
Wed, 29 Feb 2012 17:12:09 +0000 (18:12 +0100)
src/core/olsr_interface.c
src/core/olsr_interface.h
src/core/olsr_stream_socket.c
src/core/olsr_stream_socket.h
src/core/olsr_telnet.c
src/core/olsr_timer.c
src/core/olsr_timer.h
src/core/os_linux/os_system_linux.c
src/core/os_linux/os_system_linux.h
src/olsr_main.c

index 0a24228..ceb6294 100644 (file)
@@ -154,6 +154,9 @@ _interface_add(const char *name, bool mesh) {
     interf->node.key = interf->name;
     avl_insert(&olsr_interface_tree, &interf->node);
 
+    interf->change_timer.timer_info = &_change_timer_info;
+    interf->change_timer.timer_cb_context = interf;
+
     /* grab data of interface */
     os_net_update_interface(&interf->data, interf->name);
   }
@@ -250,6 +253,5 @@ _cb_change_handler(void *ptr) {
  */
 static void
 _trigger_change_timer(struct olsr_interface *interf) {
-  olsr_timer_set(&interf->change_timer,
-      OLSR_INTERFACE_CHANGE_INTERVAL, 0, interf, &_change_timer_info);
+  olsr_timer_set(&interf->change_timer, OLSR_INTERFACE_CHANGE_INTERVAL);
 }
index 77dd0b3..cb10c10 100644 (file)
@@ -95,7 +95,7 @@ struct olsr_interface {
   uint32_t _original_state;
 
   /* timer for lazy interface change handling */
-  struct olsr_timer_entry *change_timer;
+  struct olsr_timer_entry change_timer;
 };
 
 struct olsr_interface_listener {
index fbc90fa..dba9e83 100644 (file)
@@ -285,8 +285,8 @@ connect_to_error:
  * @param timeout timeout in milliseconds
  */
 void
-olsr_stream_set_timeout(struct olsr_stream_session *con, uint32_t timeout) {
-  olsr_timer_set(&con->timeout, timeout, 0, con, &connection_timeout);
+olsr_stream_set_timeout(struct olsr_stream_session *con, uint64_t timeout) {
+  olsr_timer_set(&con->timeout, timeout);
 }
 
 /**
@@ -309,8 +309,8 @@ olsr_stream_close(struct olsr_stream_session *session, bool force) {
     session->comport->config.cleanup(session);
   }
 
-  if (session->timeout) {
-    olsr_timer_stop(session->timeout);
+  if (session->timeout.timer_clock) {
+    olsr_timer_stop(&session->timeout);
   }
 
   session->comport->config.allowed_sessions++;
@@ -531,9 +531,10 @@ _create_session(struct olsr_stream_socket *stream_socket,
     session->state = STREAM_SESSION_SEND_AND_QUIT;
   }
 
+  session->timeout.timer_cb_context = session;
+  session->timeout.timer_info = &connection_timeout;
   if (stream_socket->config.session_timeout) {
-    session->timeout = olsr_timer_start(
-        stream_socket->config.session_timeout, 0, session, &connection_timeout);
+    olsr_timer_start(&session->timeout, stream_socket->config.session_timeout);
   }
 
   if (stream_socket->config.init) {
index f9ed614..a8f6bfc 100644 (file)
@@ -50,6 +50,7 @@
 #include "olsr_memcookie.h"
 #include "olsr_netaddr_acl.h"
 #include "olsr_socket.h"
+#include "olsr_timer.h"
 
 enum olsr_stream_session_state {
   STREAM_SESSION_ACTIVE,
@@ -91,7 +92,7 @@ struct olsr_stream_session {
   struct olsr_socket_entry scheduler_entry;
 
   /* timer for handling session timeout */
-  struct olsr_timer_entry *timeout;
+  struct olsr_timer_entry timeout;
 
   /* input buffer for session */
   struct autobuf in;
@@ -125,7 +126,7 @@ struct olsr_stream_config {
    * Timeout of the socket. A session will be closed if it does not
    * send or receive data for timeout milliseconds.
    */
-  uint32_t session_timeout;
+  uint64_t session_timeout;
 
   /* maximum allowed size of input buffer (default 65536) */
   size_t maximum_input_buffer;
@@ -202,7 +203,7 @@ EXPORT struct olsr_stream_session *olsr_stream_connect_to(
 EXPORT void olsr_stream_flush(struct olsr_stream_session *con);
 
 EXPORT void olsr_stream_set_timeout(
-    struct olsr_stream_session *con, uint32_t timeout);
+    struct olsr_stream_session *con, uint64_t timeout);
 EXPORT void olsr_stream_close(struct olsr_stream_session *con, bool force);
 
 EXPORT void olsr_stream_add_managed(struct olsr_stream_managed *);
index c9816ee..6cb465b 100644 (file)
@@ -579,6 +579,7 @@ _cb_telnet_timeout(struct olsr_telnet_data *data) {
 static void
 _cb_telnet_repeat_stophandler(struct olsr_telnet_data *data) {
   olsr_timer_stop((struct olsr_timer_entry *)data->stop_data[0]);
+  free(data->stop_data[0]);
   free(data->stop_data[1]);
 
   data->stop_handler = NULL;
@@ -634,7 +635,15 @@ _cb_telnet_repeat(struct olsr_telnet_data *data) {
 
   interval = atoi(data->parameter);
 
-  timer = olsr_timer_start(interval * 1000, 0, data, &_telnet_repeat_timerinfo);
+  timer = calloc(1, sizeof(*timer));
+  if (timer == NULL) {
+    return TELNET_RESULT_INTERNAL_ERROR;
+  }
+
+  timer->timer_cb_context = data;
+  timer->timer_info = &_telnet_repeat_timerinfo;
+  olsr_timer_start(timer, interval * 1000);
+
   data->stop_handler = _cb_telnet_repeat_stophandler;
   data->stop_data[0] = timer;
   data->stop_data[1] = strdup(ptr);
index 4498f75..4946d61 100644 (file)
@@ -69,10 +69,6 @@ static uint32_t _total_timer_events;
 
 /* Memory cookie for the timer manager */
 struct list_entity timerinfo_list;
-static struct olsr_memcookie_info _timer_mem_cookie = {
-  .name = "timer entry",
-  .size = sizeof(struct olsr_timer_entry),
-};
 
 /* remember if initialized or not */
 OLSR_SUBSYSTEM_STATE(_timer_state);
@@ -117,9 +113,6 @@ olsr_timer_init(void)
   _next_fire_event = ~0ull;
   _total_timer_events = 0;
 
-  /* initialize a cookie for the block based memory manager. */
-  olsr_memcookie_add(&_timer_mem_cookie);
-
   list_init_head(&timerinfo_list);
 }
 
@@ -154,9 +147,6 @@ olsr_timer_cleanup(void)
   OLSR_FOR_ALL_TIMERS(ti, iterator) {
     olsr_timer_remove(ti);
   }
-
-  /* release memory cookie for timers */
-  olsr_memcookie_remove(&_timer_mem_cookie);
 }
 
 /**
@@ -194,27 +184,18 @@ olsr_timer_remove(struct olsr_timer_info *info) {
 
 /**
  * Start a new timer.
- * @param rel_time time expressed in milliseconds
- * @param jitter_pct expressed in percent
- * @param context for the callback function
- * @param ti pointer to timer_info object
- * @return a pointer to the created entry
+ * @param timer initialized timer entry
  */
-struct olsr_timer_entry *
-olsr_timer_start(uint64_t rel_time,
-    uint8_t jitter_pct, void *context, struct olsr_timer_info *ti)
+void
+olsr_timer_start(struct olsr_timer_entry *timer, uint64_t rel_time)
 {
-  struct olsr_timer_entry *timer;
-
 #if !defined(REMOVE_LOG_DEBUG)
   struct timeval_buf timebuf;
 #endif
 
-  assert(ti != 0);
-  assert(jitter_pct <= 100);
-  assert (rel_time > 0 && rel_time < 1000ull * INT32_MAX);
-
-  timer = olsr_memcookie_malloc(&_timer_mem_cookie);
+  assert(timer->timer_info);
+  assert(timer->timer_jitter_pct <= 100);
+  assert(rel_time > 0 && rel_time < 1000ull * INT32_MAX);
 
   /*
    * Compute random numbers only once.
@@ -224,18 +205,14 @@ olsr_timer_start(uint64_t rel_time,
   }
 
   /* Fill entry */
-  timer->timer_clock = _calc_jitter(rel_time, jitter_pct, timer->timer_random);
-  timer->timer_cb_context = context;
-  timer->timer_jitter_pct = jitter_pct;
-  timer->timer_running = true;
+  timer->timer_clock = _calc_jitter(rel_time, timer->timer_jitter_pct, timer->timer_random);
 
   /* The cookie is used for debugging to traceback the originator */
-  timer->timer_info = ti;
-  ti->usage++;
-  ti->changes++;
+  timer->timer_info->usage++;
+  timer->timer_info->changes++;
 
   /* Singleshot or periodical timer ? */
-  timer->timer_period = ti->periodic ? rel_time : 0;
+  timer->timer_period = timer->timer_info->periodic ? rel_time : 0;
 
   /*
    * Now insert in the respective _timer_wheel slot.
@@ -248,10 +225,9 @@ olsr_timer_start(uint64_t rel_time,
     _next_fire_event = timer->timer_clock;
   }
 
-  OLSR_DEBUG(LOG_TIMER, "TIMER: start %s timer %p firing in %s, ctx %p\n",
-             ti->name, timer, olsr_clock_toClockString(&timebuf, timer->timer_clock), context);
-
-  return timer;
+  OLSR_DEBUG(LOG_TIMER, "TIMER: start %s timer %p firing in %s\n",
+             timer->timer_info->name, timer,
+             olsr_clock_toClockString(&timebuf, timer->timer_clock));
 }
 
 /**
@@ -261,20 +237,15 @@ olsr_timer_start(uint64_t rel_time,
 void
 olsr_timer_stop(struct olsr_timer_entry *timer)
 {
-  /* It's okay to get a NULL here */
-  if (timer == NULL) {
+  if (timer->timer_clock == 0) {
     return;
   }
 
-  OLSR_DEBUG(LOG_TIMER, "TIMER: stop %s timer %p, ctx %p\n",
-             timer->timer_info->name, timer, timer->timer_cb_context);
-
+  OLSR_DEBUG(LOG_TIMER, "TIMER: stop %s\n", timer->timer_info->name);
 
-  /*
-   * Carve out of the existing wheel_slot and free.
-   */
+  /* remove timer from buckets */
   list_remove(&timer->_node);
-  timer->timer_running = false;
+  timer->timer_clock = 0;
   timer->timer_info->usage--;
   timer->timer_info->changes++;
 
@@ -283,10 +254,6 @@ olsr_timer_stop(struct olsr_timer_entry *timer)
   if (_next_fire_event == timer->timer_clock) {
     _calculate_next_event();
   }
-
-  if (!timer->timer_in_callback) {
-    olsr_memcookie_free(&_timer_mem_cookie, timer);
-  }
 }
 
 /**
@@ -296,7 +263,7 @@ olsr_timer_stop(struct olsr_timer_entry *timer)
  * @param jitter_pct new jitter expressed in percent.
  */
 void
-olsr_timer_change(struct olsr_timer_entry *timer, uint64_t rel_time, uint8_t jitter_pct)
+olsr_timer_change(struct olsr_timer_entry *timer, uint64_t rel_time)
 {
 #if !defined(REMOVE_LOG_DEBUG)
   struct timeval_buf timebuf;
@@ -316,8 +283,7 @@ olsr_timer_change(struct olsr_timer_entry *timer, uint64_t rel_time, uint8_t jit
   /* Singleshot or periodical timer ? */
   timer->timer_period = timer->timer_info->periodic ? rel_time : 0;
 
-  timer->timer_clock = _calc_jitter(rel_time, jitter_pct, timer->timer_random);
-  timer->timer_jitter_pct = jitter_pct;
+  timer->timer_clock = _calc_jitter(rel_time, timer->timer_jitter_pct, timer->timer_random);
 
   /*
    * Changes are easy: Remove timer from the existing _timer_wheel slot
@@ -334,9 +300,9 @@ olsr_timer_change(struct olsr_timer_entry *timer, uint64_t rel_time, uint8_t jit
     _calculate_next_event();
   }
 
-  OLSR_DEBUG(LOG_TIMER, "TIMER: change %s timer, firing to %s, ctx %p\n",
+  OLSR_DEBUG(LOG_TIMER, "TIMER: change %s timer, firing to %s\n",
              timer->timer_info->name,
-             olsr_clock_toClockString(&timebuf, timer->timer_clock), timer->timer_cb_context);
+             olsr_clock_toClockString(&timebuf, timer->timer_clock));
 }
 
 /**
@@ -346,27 +312,20 @@ olsr_timer_change(struct olsr_timer_entry *timer, uint64_t rel_time, uint8_t jit
  * terminated.
  * @param timer_ptr pointer to timer_entry pointer
  * @param rel_time time until the new timer should fire, 0 to stop timer
- * @param jitter_pct jitter of timer in percent
- * @param context context pointer of timer
- * @param ti timer_info of timer
  */
 void
-olsr_timer_set(struct olsr_timer_entry **timer_ptr,
-               uint64_t rel_time,
-               uint8_t jitter_pct, void *context, struct olsr_timer_info *ti)
+olsr_timer_set(struct olsr_timer_entry *timer, uint64_t rel_time)
 {
-  assert(ti);          /* we want timer cookies everywhere */
   if (rel_time == 0) {
     /* No good future time provided, kill it. */
-    olsr_timer_stop(*timer_ptr);
-    *timer_ptr = NULL;
+    olsr_timer_stop(timer);
   }
-  else if ((*timer_ptr) == NULL) {
+  else if (timer->timer_clock == 0) {
     /* No timer running, kick it. */
-    *timer_ptr = olsr_timer_start(rel_time, jitter_pct, context, ti);
+    olsr_timer_start(timer, rel_time);
   }
   else {
-    olsr_timer_change(*timer_ptr, rel_time, jitter_pct);
+    olsr_timer_change(timer, rel_time);
   }
 }
 
@@ -389,13 +348,14 @@ olsr_timer_walk(void)
                   timer, timer->timer_cb_context, _next_fire_event);
 
        /* This timer is expired, call into the provided callback function */
-       timer->timer_in_callback = true;
        timer->timer_info->callback(timer->timer_cb_context);
-       timer->timer_in_callback = false;
        timer->timer_info->changes++;
 
-       /* Only act on actually running timers */
-       if (timer->timer_running) {
+       /*
+        * Only act on actually running timers, the callback might have
+        * called olsr_timer_stop() !
+        */
+       if (timer->timer_clock) {
          /*
           * Don't restart the periodic timer if the callback function has
           * stopped the timer.
@@ -403,16 +363,12 @@ olsr_timer_walk(void)
          if (timer->timer_period) {
            /* For periodical timers, rehash the random number and restart */
            timer->timer_random = random();
-           olsr_timer_change(timer, timer->timer_period, timer->timer_jitter_pct);
+           olsr_timer_change(timer, timer->timer_period);
          } else {
            /* Singleshot timers are stopped */
            olsr_timer_stop(timer);
          }
        }
-       else {
-         /* free memory */
-         olsr_memcookie_free(&_timer_mem_cookie, timer);
-       }
     }
 
     /* advance our 'next event' marker */
index 036ae0d..7133853 100644 (file)
@@ -97,12 +97,6 @@ struct olsr_timer_entry {
   /* the jitter expressed in percent */
   uint8_t timer_jitter_pct;
 
-  /* true if timer is running at the moment */
-  bool timer_running;
-
-  /* true if timer is in callback at the moment */
-  bool timer_in_callback;
-
   /* cache random() result for performance reasons */
   unsigned int timer_random;
 
@@ -121,11 +115,9 @@ EXPORT void olsr_timer_walk(void);
 EXPORT void olsr_timer_add(struct olsr_timer_info *ti);
 EXPORT void olsr_timer_remove(struct olsr_timer_info *);
 
-EXPORT void olsr_timer_set(struct olsr_timer_entry **, uint64_t, uint8_t,
-    void *, struct olsr_timer_info *);
-EXPORT struct olsr_timer_entry *olsr_timer_start(uint64_t, uint8_t,
-    void *, struct olsr_timer_info *);
-EXPORT void olsr_timer_change(struct olsr_timer_entry *, uint64_t, uint8_t);
+EXPORT void olsr_timer_set(struct olsr_timer_entry *timer, uint64_t rel_time);
+EXPORT void olsr_timer_start(struct olsr_timer_entry *timer, uint64_t rel_time);
+EXPORT void olsr_timer_change(struct olsr_timer_entry *, uint64_t);
 EXPORT void olsr_timer_stop(struct olsr_timer_entry *);
 
 EXPORT uint64_t olsr_timer_getNextEvent(void);
index f95d422..5ff428a 100644 (file)
@@ -255,6 +255,9 @@ os_system_netlink_add(struct os_system_netlink *nl, int protocol, uint32_t multi
   nl->socket.data = nl;
   olsr_socket_add(&nl->socket);
 
+  nl->timeout.timer_cb_context = nl;
+  nl->timeout.timer_info = &_netlink_timer;
+
   return 0;
 
 os_add_netlink_fail:
@@ -341,8 +344,6 @@ static void
 _cb_handle_netlink_timerout(void *ptr) {
   struct os_system_netlink *nl = ptr;
 
-  nl->timeout = NULL;
-
   if (nl->cb_timeout) {
     nl->cb_timeout();
   }
@@ -359,7 +360,7 @@ _flush_netlink_buffer(struct os_system_netlink *nl) {
   ssize_t ret;
 
   /* start feedback timer */
-  olsr_timer_set(&nl->timeout, OS_SYSTEM_NETLINK_TIMEOUT, 0, nl, &_netlink_timer);
+  olsr_timer_set(&nl->timeout, OS_SYSTEM_NETLINK_TIMEOUT);
 
   /* send outgoing message */
   _netlink_send_iov[0].iov_base = abuf_getptr(&nl->out);
@@ -391,8 +392,7 @@ _netlink_job_finished(struct os_system_netlink *nl) {
     nl->msg_in_transit--;
   }
   if (nl->msg_in_transit == 0) {
-    olsr_timer_stop(nl->timeout);
-    nl->timeout= NULL;
+    olsr_timer_stop(&nl->timeout);
     nl->seq_used = 0;
   }
 }
index e016954..6026ae7 100644 (file)
@@ -40,7 +40,7 @@ struct os_system_netlink {
   void (*cb_timeout)(void);
   void (*cb_done)(uint32_t seq);
 
-  struct olsr_timer_entry *timeout;
+  struct olsr_timer_entry timeout;
 };
 
 EXPORT int os_system_netlink_add(struct os_system_netlink *,
index ea88069..ad2c811 100644 (file)
@@ -356,59 +356,14 @@ hup_signal_handler(int signo __attribute__ ((unused))) {
   olsr_cfg_trigger_reload();
 }
 
-static struct olsr_timer_info _test_timer_info;
-
-static void _cb_test(void *t __attribute__((unused))) {
-  fprintf(stderr, "Fire %" PRIu64 "\n", olsr_clock_getNow());
-
-//  olsr_timer_start((random() % 20000) + 1000, 0, NULL, &_test_timer_info);
-}
-static struct olsr_timer_info _test_timer_info = {
-    .name = "test",
-    .callback = _cb_test,
-    .periodic = false,
-};
-
-static int cmp(const void *a, const void *b) {
-  const uint64_t *a64 = a;
-  const uint64_t *b64 = b;
-
-  if (*a64 < *b64)
-    return -1;
-  if (*a64 > *b64)
-    return 1;
-  return 0;
-}
 /**
  * Mainloop of olsrd
  * @return exit code for olsrd
  */
 static int
 mainloop(int argc, char **argv) {
-  static uint64_t starts[3];
   uint64_t next_interval;
   int exit_code = 0;
-  size_t i;
-
-  olsr_timer_add(&_test_timer_info);
-
-  for (i=0; i< ARRAYSIZE(starts); i++) {
-    starts[i] = (uint64_t)(random() % 600000) + 1000ull;
-  }
-
-  starts[0] = 4526;
-  starts[1] = 11012;
-  starts[2] = 39335;
-
-  qsort(starts, ARRAYSIZE(starts), sizeof(uint64_t), cmp);
-
-  for (i=0; i<ARRAYSIZE(starts); i++) {
-    fprintf(stderr, "Random start: %" PRIu64" / %" PRIu64 "\n", starts[i], i==0 ? 0 : starts[i]-starts[i-1]);
-  }
-
-  for (i=0; i< ARRAYSIZE(starts); i++) {
-    olsr_timer_start(starts[i], 0, NULL, &_test_timer_info);
-  }
 
   OLSR_INFO(LOG_MAIN, "Starting %s.", olsr_log_get_builddata()->app_name);