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.
static sel_timer it;
#define T_INTERVAL MIN(1)
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@ --- *
*
/* --- @interval@ --- *
*
static void interval(struct timeval *tv, void *v)
{
static void interval(struct timeval *tv, void *v)
{
T( trace(T_PEER, "peer: interval timer"); )
T( trace(T_PEER, "peer: interval timer"); )
rand_seed(RAND_GLOBAL, MAXHASHSZ);
p_interval();
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
/* --- @main@ --- *
*
* Arguments: @int argc@ = number of command line arguments
int i;
int err, selerr = 0;
unsigned af;
int i;
int err, selerr = 0;
unsigned af;
uid_t u = -1;
gid_t g = -1;
uid_t u = -1;
gid_t g = -1;
- 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();
for (;;) {
a_preselect();
extern peer *p_next(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
/*----- Tunnel drivers ----------------------------------------------------*/
#ifdef TUN_LINUX