Browse Source

[Minor] Deal with descriptors in the wait queue

pull/4937/head
Vsevolod Stakhov 1 week ago
parent
commit
6dd417bc9f
No account linked to committer's email address
1 changed files with 39 additions and 2 deletions
  1. 39
    2
      src/libserver/rspamd_control.c

+ 39
- 2
src/libserver/rspamd_control.c View File

@@ -361,6 +361,10 @@ void rspamd_pending_control_free(gpointer p)
if (rep_elt->sent) {
rspamd_ev_watcher_stop(rep_elt->event_loop, &rep_elt->ev);
}
else if (rep_elt->attached_fd != -1) {
/* Only for non-sent requests! */
close(rep_elt->attached_fd);
}

g_hash_table_unref(rep_elt->pending_elts);
g_free(rep_elt);
@@ -439,6 +443,11 @@ rspamd_control_stop_pending(struct rspamd_control_reply_elt *elt)
rspamd_ev_watcher_start(cur->event_loop,
&cur->ev, worker_io_timeout);
cur->sent = true;
if (cur->attached_fd != -1) {
/* Since `sendmsg` performs `dup` for us, we need to remove our own descriptor */
close(cur->attached_fd);
cur->attached_fd = -1;
}

break; /* Exit the outer loop as we have invoked something */
}
@@ -501,6 +510,7 @@ rspamd_control_broadcast_cmd(struct rspamd_main *rspamd_main,
rep_elt->handler = handler;
memcpy(&rep_elt->cmd, cmd, sizeof(*cmd));
rep_elt->sent = false;
rep_elt->attached_fd = -1;

if (g_hash_table_size(wrk->control_events_pending) == 0) {
/* We can send command */
@@ -545,8 +555,35 @@ rspamd_control_broadcast_cmd(struct rspamd_main *rspamd_main,
g_quark_to_string(wrk->type),
(int) g_hash_table_size(wrk->control_events_pending));
rep_elt->pending_elts = g_hash_table_ref(wrk->control_events_pending);
g_hash_table_insert(wrk->control_events_pending, rep_elt, rep_elt);
DL_APPEND(res, rep_elt);
/*
* Here are dragons:
* If we have a descriptor to send, the callee expects that we follow
* sendmsg semantics that performs `dup` on it. So we need to clone fd and keep it there.
*/
if (attached_fd != -1) {
rep_elt->attached_fd = dup(attached_fd);

if (rep_elt->attached_fd == -1) {
/*
* We have a problem: file descriptors limit is reached, so we cannot really deal with this
* request
*/
msg_err_main("cannot duplicate file descriptor to send command to worker %P(%s): %s; failed to send command",
wrk->pid,
g_quark_to_string(wrk->type),
strerror(errno));
g_hash_table_unref(rep_elt->pending_elts);
g_free(rep_elt);
}
else {
g_hash_table_insert(wrk->control_events_pending, rep_elt, rep_elt);
DL_APPEND(res, rep_elt);
}
}
else {
g_hash_table_insert(wrk->control_events_pending, rep_elt, rep_elt);
DL_APPEND(res, rep_elt);
}
}
}


Loading…
Cancel
Save