I am implementing a web server where I need to make the parent process do the following:
fork()new worker processes (a pool) at the beginning.- Looping forever, listening for incoming requests (via socket communication).
- Putting the socket descriptor (returned by
accept()function) into a queue.
and the worker process will do the following:
- Once created, loops forever watching the queue for any passed socket descriptors.
- If he takes the socket descriptor, he handles the request and serves the client accordingly.
After looking around and searching the internet, I found that I can send a file descriptor between different processes via UNIX Domain Socket or Pipes. But unfortunately, I can do this synchronously only! (I can send one fd at a time, and I cannot put it in a waiting queue)
So, my question is:
- How can I make the parent process puts the socket descriptor into a waiting queue, so that, the request is pending until one of the worker processes finishes a previous request?
File descriptors are just integers. They are used to index into a per-process table of file information, maintained by the kernel. You can’t expect a file descriptor to be “portable” to other processes.
It works (somewhat) if you create the files before calling
fork(), since the file descriptor table is part of the process and thusclone()d when the child is created. For file descriptors allocated after the processes have split, such as when usingaccept()to get a new socket, you can’t do this.UPDATE: It seems there is a way, using
sendmsg()with AF_UNIX sockets, see here for details as mentioned in this question. I did not know that, sounds a bit “magical” but apparently it’s a well-established mechanism so why not go ahead and implement that.