return 0;
}
+/**
+ * Clean up any finished TID request processes
+ *
+ * This is called by the main process after forking each TID request. If you want to be
+ * sure finished processes are cleaned up promptly even during a lull in TID requests,
+ * this can be called from the main thread of the main process. It is not thread-safe,
+ * so should not be used from sub-threads. It should not be called by child processes -
+ * this would probably be harmless but ineffective.
+ *
+ * @param tids
+ */
void tids_sweep_procs(TIDS_INSTANCE *tids)
{
guint ii;
struct cmdline_args opts;
struct event_base *ev_base;
struct tr_socket_event tids_ev = {0};
+ struct event *tids_sweep_ev;
struct tr_socket_event mon_ev = {0};
struct event *cfgwatch_ev;
/* install TID server events */
tr_debug("Initializing TID server events.");
- if (0 != tr_tids_event_init(ev_base,
- tr->tids,
- tr->cfg_mgr,
- tr->trps,
- &tids_ev)) {
+ if (0 != tr_tids_event_init(ev_base, tr->tids, tr->cfg_mgr, tr->trps, &tids_ev, &tids_sweep_ev)) {
tr_crit("Error initializing Trust Path Query Server instance.");
return 1;
}
/* called when a connection to the TIDS port is received */
static void tr_tids_event_cb(int listener, short event, void *arg)
{
- TIDS_INSTANCE *tids = (TIDS_INSTANCE *)arg;
+ TIDS_INSTANCE *tids = talloc_get_type_abort(arg, TIDS_INSTANCE);
if (0==(event & EV_READ))
tr_debug("tr_tids_event_cb: unexpected event on TIDS socket (event=0x%X)", event);
tids_accept(tids, listener);
}
-/* Configure the tids instance and set up its event handler.
+/* called when it's time to sweep for completed TID child processes */
+static void tr_tids_sweep_cb(int listener, short event, void *arg)
+{
+ TIDS_INSTANCE *tids = talloc_get_type_abort(arg, TIDS_INSTANCE);
+
+ if (0==(event & EV_TIMEOUT))
+ tr_debug("tr_tids_event_cb: unexpected event on TID process sweep timer (event=0x%X)", event);
+ else
+ tids_sweep_procs(tids);
+}
+
+/* Configure the tids instance and set up its event handlers.
* Returns 0 on success, nonzero on failure. Fills in
* *tids_event (which should be allocated by caller). */
-int tr_tids_event_init(struct event_base *base,
- TIDS_INSTANCE *tids,
- TR_CFG_MGR *cfg_mgr,
- TRPS_INSTANCE *trps,
- struct tr_socket_event *tids_ev)
+int tr_tids_event_init(struct event_base *base, TIDS_INSTANCE *tids, TR_CFG_MGR *cfg_mgr, TRPS_INSTANCE *trps,
+ struct tr_socket_event *tids_ev, struct event **sweep_ev)
{
TALLOC_CTX *tmp_ctx=talloc_new(NULL);
struct tr_tids_event_cookie *cookie=NULL;
+ struct timeval sweep_interval;
int retval=0;
int ii=0;
goto cleanup;
}
+ if (sweep_ev == NULL) {
+ tr_debug("tr_tids_event_init: Null sweep_ev.");
+ retval = 1;
+ goto cleanup;
+ }
+
/* Create the cookie for callbacks. We'll put it in the tids context, so it will
* be cleaned up when tids is freed by talloc_free. */
cookie=talloc(tmp_ctx, struct tr_tids_event_cookie);
goto cleanup;
}
- /* Set up events */
+ /* Set up listener events */
for (ii=0; ii<tids_ev->n_sock_fd; ii++) {
tids_ev->ev[ii]=event_new(base,
tids_ev->sock_fd[ii],
event_add(tids_ev->ev[ii], NULL);
}
+ /* Set up a periodic check for completed TID handler processes */
+ *sweep_ev = event_new(base, -1, EV_TIMEOUT|EV_PERSIST, tr_tids_sweep_cb, tids);
+ sweep_interval.tv_sec = 10;
+ sweep_interval.tv_usec = 0;
+ event_add(*sweep_ev, &sweep_interval);
+
cleanup:
talloc_free(tmp_ctx);
return retval;