server/tripe.c: Formalize the interval-timer arrangements.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 19 May 2018 17:28:15 +0000 (18:28 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Fri, 25 Jan 2019 12:10:32 +0000 (12:10 +0000)
The hard stuff is now (mostly) detached from the main initialization
code.  There's also some machinery, currently unused, for disabling the
interval timer while it's not doing any good, which might be useful in
energy-constrained devices.

server/tripe.c
server/tripe.h

index 93d40b9..e4733bc 100644 (file)
@@ -36,7 +36,10 @@ sel_state sel;
 static sel_timer it;
 #define T_INTERVAL MIN(1)
 
-/*----- Main code ---------------------------------------------------------*/
+static unsigned iv_nreasons = 0;
+static struct timeval iv_next = { 0, 0 };
+
+/*----- The interval timer ------------------------------------------------*/
 
 /* --- @interval@ --- *
  *
@@ -50,15 +53,54 @@ static sel_timer it;
 
 static void interval(struct timeval *tv, void *v)
 {
-  struct timeval tvv;
   T( trace(T_PEER, "peer: interval timer"); )
+  iv_next = *tv;
   rand_seed(RAND_GLOBAL, MAXHASHSZ);
   p_interval();
-  tvv = *tv;
-  tvv.tv_sec += T_INTERVAL;
-  sel_addtimer(&sel, &it, &tvv, interval, v);
+  iv_next.tv_sec += T_INTERVAL;
+  sel_addtimer(&sel, &it, &iv_next, interval, v);
+}
+
+/* --- @iv_addreason@ --- *
+ *
+ * Arguments:  ---
+ *
+ * Returns:    ---
+ *
+ * Use:                Adds an `interval timer reason'; if there are no others, the
+ *             interval timer is engaged.
+ */
+
+void iv_addreason(void)
+{
+  struct timeval tv;
+
+  if (!iv_nreasons) {
+    gettimeofday(&tv, 0);
+    if (TV_CMP(&tv, >=, &iv_next)) interval(&tv, 0);
+    else sel_addtimer(&sel, &it, &iv_next, interval, 0);
+  }
+  iv_nreasons++;
 }
 
+/* --- @iv_rmreason@ --- *
+ *
+ * Arguments:  ---
+ *
+ * Returns:    ---
+ *
+ * Use:                Removes an interval timer reason; if there are none left, the
+ *             interval timer is disengaged.
+ */
+
+void iv_rmreason(void)
+{
+  assert(iv_nreasons); iv_nreasons--;
+  if (!iv_nreasons) sel_rmtimer(&it);
+}
+
+/*----- Main code ---------------------------------------------------------*/
+
 /* --- @main@ --- *
  *
  * Arguments:  @int argc@ = number of command line arguments
@@ -127,7 +169,6 @@ int main(int argc, char *argv[])
   int i;
   int err, selerr = 0;
   unsigned af;
-  struct timeval tv;
   uid_t u = -1;
   gid_t g = -1;
 
@@ -331,9 +372,8 @@ int main(int argc, char *argv[])
     a_switcherr();
   }
 
-  tv.tv_sec = time(0) + T_INTERVAL;
-  tv.tv_usec = 0;
-  sel_addtimer(&sel, &it, &tv, interval, 0);
+  gettimeofday(&iv_next, 0); iv_next.tv_sec += T_INTERVAL;
+  iv_addreason();
 
   for (;;) {
     a_preselect();
index 9ff5456..a2fdd00 100644 (file)
@@ -1829,6 +1829,32 @@ extern void p_mkiter(peer_iter */*i*/);
 
 extern peer *p_next(peer_iter */*i*/);
 
+/*----- The interval timer ------------------------------------------------*/
+
+/* --- @iv_addreason@ --- *
+ *
+ * Arguments:  ---
+ *
+ * Returns:    ---
+ *
+ * Use:                Adds an `interval timer reason'; if there are no others, the
+ *             interval timer is engaged.
+ */
+
+extern void iv_addreason(void);
+
+/* --- @iv_rmreason@ --- *
+ *
+ * Arguments:  ---
+ *
+ * Returns:    ---
+ *
+ * Use:                Removes an interval timer reason; if there are none left, the
+ *             interval timer is disengaged.
+ */
+
+extern void iv_rmreason(void);
+
 /*----- Tunnel drivers ----------------------------------------------------*/
 
 #ifdef TUN_LINUX