skip close_on_exec() - #3713
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 273bcfa2ee
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| @@ -106,17 +106,9 @@ def init_process(self): | |||
| self.PIPE = os.pipe() | |||
| for p in self.PIPE: | |||
| util.set_non_blocking(p) | |||
There was a problem hiding this comment.
Restore CLOEXEC on worker listener sockets
When application code forks and execs a child without closing file descriptors (for example, subprocess.Popen(..., close_fds=False)), that child now inherits every Gunicorn listener. BaseSocket.set_options() deliberately marks listeners inheritable for the master's re-exec path, so PEP 446 does not protect them; this worker-side loop was what reversed that setting after the fork. A long-lived child can therefore keep the listening port bound after Gunicorn shuts down and prevent a clean restart, so the listeners still need to be made non-inheritable during worker initialization.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
The Arbitor of gunicorn uses os.fork() instead of Popen(). When creating self.LISTENERS, it is not set to inheritable, so it remains non-inheritable from the parent process. It is not necessary to set it after forking in the child process.
| """ | ||
| self.log.close_on_exec() | ||
|
|
||
| # initialize all signals |
There was a problem hiding this comment.
Continue invoking custom logger CLOEXEC hooks
When --logger-class supplies a custom logger whose close_on_exec() handles inherited or explicitly inheritable logging descriptors, this removal silently stops invoking that hook in both the master and workers. PEP 446 only changes defaults for descriptors created by Python and cannot replace custom cleanup logic, so those descriptors can leak through a master re-exec or an exec launched by application code; retain the lifecycle call even if the built-in logger implementation no longer needs to do work.
Useful? React with 👍 / 👎.
It is default since in Python 3.4.
https://peps.python.org/pep-0446/