int fr_event_list_time(struct timeval *when, fr_event_list_t *el);
int fr_event_fd_delete(fr_event_list_t *el, int fd);
-int fr_event_fd_insert(fr_event_list_t *el, int fd,
+int fr_event_fd_insert(TALLOC_CTX *ctx, fr_event_list_t *el, int fd,
fr_event_fd_handler_t read_fn,
fr_event_fd_handler_t write_fn,
fr_event_fd_error_handler_t error,
rad_assert(app_io->fd);
fd = app_io->fd(s->listen->app_io_instance);
- if (fr_event_fd_insert(nr->el, fd,
+ if (fr_event_fd_insert(nr, nr->el, fd,
fr_network_read,
NULL, /* app_io->write ? fr_network_write : NULL - FIXME */
app_io->error ? fr_network_error : NULL,
//!< the handlers complete.
void *uctx; //!< Context pointer to pass to each file descriptor callback.
+ TALLOC_CTX *linked_ctx; //!< talloc ctx this event was bound to.
} fr_event_fd_t;
/** Callbacks to perform when the event handler is about to check the events.
/** Associate a callback with an file descriptor
*
+ * @param[in] ctx to bind lifetime of the event to.
* @param[in] el to insert fd callback into.
* @param[in] fd to read from.
* @param[in] read_fn function to call when fd is readable.
* - 0 on succes.
* - -1 on failure.
*/
-int fr_event_fd_insert(fr_event_list_t *el, int fd,
+int fr_event_fd_insert(TALLOC_CTX *ctx, fr_event_list_t *el, int fd,
fr_event_fd_handler_t read_fn,
fr_event_fd_handler_t write_fn,
fr_event_fd_error_handler_t error,
find.fd = fd;
ef = rbtree_finddata(el->fds, &find);
+ /*
+ * Need to free the event to change the
+ * talloc link.
+ */
+ if (ef && (ef->linked_ctx != ctx)) TALLOC_FREE(ef); /* Also cleans up kevent filters */
+
/*
* No pre-existing event. Allocate an entry
* for insertion into the rbtree, and call
ef->write = write_fn;
ef->error = error;
ef->is_registered = true;
+ ef->linked_ctx = ctx;
return 0;
}
* If connection becomes writable we
* assume it's open.
*/
- if (fr_event_fd_insert(conn->el, fd, NULL, _connection_writable, _connection_error, conn) < 0) {
+ if (fr_event_fd_insert(conn, conn->el, fd, NULL, _connection_writable, _connection_error, conn) < 0) {
PERROR("Failed inserting file descriptor (%i) into event loop %p", fd, conn->el);
connection_state_failed(conn, now);
return;
}
DEBUG4("Created signal pipe. Read end FD %i, write end FD %i", self_pipe[0], self_pipe[1]);
- if (fr_event_fd_insert(event_list, self_pipe[0], event_signal_handler, NULL, NULL, event_list) < 0) {
+ if (fr_event_fd_insert(NULL, event_list, self_pipe[0], event_signal_handler, NULL, NULL, event_list) < 0) {
PERROR("Failed creating signal pipe handler");
return -1;
}
exit(EXIT_FAILURE);
}
- if (fr_event_fd_insert(events, self_pipe[0], rs_signal_action, NULL, NULL, events) < 0) {
+ if (fr_event_fd_insert(NULL, events, self_pipe[0], rs_signal_action, NULL, NULL, events) < 0) {
ERROR("Failed inserting signal pipe descriptor: %s", fr_strerror());
goto finish;
}
event->out = out;
event->stats = stats;
- if (fr_event_fd_insert(events, in_p->fd, rs_got_packet, NULL, NULL, event) < 0) {
+ if (fr_event_fd_insert(NULL, events, in_p->fd, rs_got_packet, NULL, NULL, event) < 0) {
ERROR("Failed inserting file descriptor");
goto finish;
}
local_backlog = fr_heap_create(timestamp_cmp, offsetof(REQUEST, heap_id));
rad_assert(local_backlog != NULL);
- if (fr_event_fd_insert(el, thread->pipe_fd[0], thread_fd_handler, NULL, NULL, thread) < 0) {
+ if (fr_event_fd_insert(thread, el, thread->pipe_fd[0], thread_fd_handler, NULL, NULL, thread) < 0) {
ERROR("Failed inserting event for self");
goto done;
}
/*
* Register for events on the file descriptor
*/
- if (fr_event_fd_insert(request->el, fd,
+ if (fr_event_fd_insert(request, request->el, fd,
ev->fd_read ? unlang_event_fd_read_handler : NULL,
ev->fd_write ? unlang_event_fd_write_handler : NULL,
ev->fd_error ? unlang_event_fd_error_handler: NULL, ev) < 0) {
fcntl(session->pipefd[1], F_SETFL, O_NONBLOCK | FD_CLOEXEC);
#endif
- if (fr_event_fd_insert(session->el, session->pipefd[0], bfd_pipe_recv, NULL, NULL, session) < 0) {
+ if (fr_event_fd_insert(session, session->el, session->pipefd[0], bfd_pipe_recv, NULL, NULL, session) < 0) {
PERROR("Failed inserting file descriptor into event list");
goto close_pipes;
}
static void logtee_fd_idle(rlm_logtee_thread_t *t)
{
DEBUG3("Marking socket (%i) as idle", fr_connection_get_fd(t->conn));
- if (fr_event_fd_insert(t->el, fr_connection_get_fd(t->conn),
+ if (fr_event_fd_insert(t, t->el, fr_connection_get_fd(t->conn),
_logtee_conn_read, NULL, _logtee_conn_error, t) < 0) {
PERROR("Failed inserting FD event");
}
static void logtee_fd_active(rlm_logtee_thread_t *t)
{
DEBUG3("Marking socket (%i) as active - Draining requests", fr_connection_get_fd(t->conn));
- if (fr_event_fd_insert(t->el, fr_connection_get_fd(t->conn),
+ if (fr_event_fd_insert(t, t->el, fr_connection_get_fd(t->conn),
_logtee_conn_read, _logtee_conn_writable, _logtee_conn_error, t) < 0) {
PERROR("Failed inserting FD event");
}
switch (what) {
case CURL_POLL_IN:
- if (fr_event_fd_insert(thread->el, fd,
+ if (fr_event_fd_insert(thread, thread->el, fd,
_rest_io_service_readable, NULL, _rest_io_service_errored,
thread) < 0) {
ERROR("multi-handle %p registration failed for read+error events on FD %i: %s",
break;
case CURL_POLL_OUT:
- if (fr_event_fd_insert(thread->el, fd,
+ if (fr_event_fd_insert(thread, thread->el, fd,
NULL, _rest_io_service_writable, _rest_io_service_errored,
thread) < 0) {
ERROR("multi-handle %p registration failed for write+error events on FD %i: %s",
break;
case CURL_POLL_INOUT:
- if (fr_event_fd_insert(thread->el, fd,
+ if (fr_event_fd_insert(thread, thread->el, fd,
_rest_io_service_readable, _rest_io_service_writable, _rest_io_service_errored,
thread) < 0) {
ERROR("multi-handle %p registration failed for read+write+error events on FD %i: %s",
inst->log_fd = ub_fd(inst->ub);
if (inst->log_fd >= 0) {
- if (fr_event_fd_insert(inst->el, inst->log_fd, ub_fd_handler, NULL, NULL, inst) < 0) {
+ if (fr_event_fd_insert(inst, inst->el, inst->log_fd, ub_fd_handler, NULL, NULL, inst) < 0) {
cf_log_err(conf, "could not insert async fd");
inst->log_fd = -1;
goto error_nores;