Closing sockets and terminating context after fork leaks fds
Issue description
After forking, closing sockets and terminating the context leaves file descriptors open. I believe this is because the socket close expects a separate thread to handle closing the fd, but the thread is gone after fork.
Environment
- libzmq version (commit hash if unreleased):
- OS:
Minimal test code / Steps to reproduce the issue
To reproduce, compile and run the following code, and inspect open fds with lsof.
#include <unistd.h>
#include <zmq.h>
int main() {
void *ctx = zmq_ctx_new();
void *sock = zmq_socket(ctx, ZMQ_ROUTER);
zmq_bind(sock, "tcp://*:7919");
pid_t pid = fork();
if (pid == 0) {
zmq_close(sock);
zmq_ctx_term(ctx);
}
sleep(300);
return 0;
}
What's the actual result? (include assertion message & call stack if applicable)
The child process still has these file descriptors open:
zeromqfor 17872 root 3u a_inode 0,13 0 9013 [eventfd]
zeromqfor 17872 root 4u a_inode 0,13 0 9013 [eventfd]
zeromqfor 17872 root 5u a_inode 0,13 0 9013 [eventpoll]
zeromqfor 17872 root 6u a_inode 0,13 0 9013 [eventfd]
zeromqfor 17872 root 7u a_inode 0,13 0 9013 [eventpoll]
zeromqfor 17872 root 8u a_inode 0,13 0 9013 [eventfd]
zeromqfor 17872 root 9u IPv4 22940606 0t0 TCP *:7919 (LISTEN)
What's the expected result?
The zmq_close and zmq_ctx_term in the child should close these file descriptors.
I may be wrong here re zmq specifics, but generally when handles have a lifetime intersected by a fork() then both parent and client need to close the handle. i.e.
int handle = open(...);
pid = fork();
// now <handle> is 'live' in both parent and child.
// *One* side is supposed to do something with it, re *work*, e.g.
if (pid) {
do_work_with(handle);
close(handle);
} else {
// close *immediately*
close(handle);
}
Without knowing the particulars of zmq (just new here!), the above is the generic pattern around a fork, so that would make your code look like this:
if (pid == 0) {
zmq_close(sock);
zmq_ctx_term(ctx);
} else {
do_your_work_with(sock);
zmq_close(sock);
zmq_ctx_term(ctx);
}
This issue has been automatically marked as stale because it has not had activity for 365 days. It will be closed if no further activity occurs within 56 days. Thank you for your contributions.