+ 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);
+}
+
+/*----- The main loop -----------------------------------------------------*/
+
+/* --- @lp_init@ --- *
+ *
+ * Arguments: ---
+ *
+ * Returns: ---
+ *
+ * Use: Initializes the main loop. Most importantly, this sets up
+ * the select multiplexor that everything else hooks onto.
+ */
+
+void lp_init(void)
+{
+ rand_noisesrc(RAND_GLOBAL, &noise_source);
+ rand_seed(RAND_GLOBAL, MAXHASHSZ);
+ gettimeofday(&iv_next, 0); iv_next.tv_sec += T_INTERVAL;
+ signal(SIGPIPE, SIG_IGN);
+ sel_init(&sel);
+ sig_init(&sel);