Re: Unportable implementation of background worker start
Tom Lane <tgl@sss.pgh.pa.us>
Attachments
- make-postmaster-use-WaitEventSet-v1.patch (text/x-diff) patch v1
Attached is a lightly-tested draft patch that converts the postmaster to
use a WaitEventSet for waiting in ServerLoop. I've got mixed emotions
about whether this is the direction to proceed, though. It adds at least
a couple of kernel calls per postmaster signal delivery, and probably to
every postmaster connection acceptance (ServerLoop iteration), to fix
problems that are so corner-casey that we've never even known we had them
till now.
I'm looking longingly at pselect(2), ppoll(2), and epoll_pwait(2), which
would solve the problem without need for a self-pipe. But the latter two
are Linux-only, and while pselect does exist in recent POSIX editions,
it's nonetheless got portability issues. Googling suggests that on a
number of platforms, pselect is non-atomic, ie it's nothing but a
wrapper for sigprocmask/select/sigprocmask, which would mean that the
race condition I described in my previous message still exists.
Despite that, a pretty attractive proposal is to do, essentially,
#ifdef HAVE_PSELECT
selres = pselect(nSockets, &rmask, NULL, NULL, &timeout, &UnBlockSig);
#else
PG_SETMASK(&UnBlockSig);
selres = select(nSockets, &rmask, NULL, NULL, &timeout);
PG_SETMASK(&BlockSig);
#endif
This fixes the race on platforms where pselect exists and is correctly
implemented, and we're no worse off than before where that's not true.
The other component of the problem is the possibility that select() will
restart if the signal is marked SA_RESTART. (Presumably that would apply
to pselect too.) I am thinking that maybe the answer is "if it hurts,
don't do it" --- that is, in the postmaster maybe we shouldn't use
SA_RESTART, at least not for these signals.
A different line of thought is to try to provide a bulletproof solution,
but push the implementation problems down into latch.c --- that is, the
goal would be to provide a pselect-like variant of WaitEventSetWait that
is guaranteed to return if interrupted, as opposed to the current behavior
where it's guaranteed not to. But that seems like quite a bit of work.
Whether or not we decide to change over the postmaster.c code, I think
it'd likely be a good idea to apply most or all of the attached changes
in latch.c. Setting CLOEXEC on the relevant FDs is clearly a good thing,
and the other changes will provide some safety if some preloaded extension
decides to create a latch in the postmaster process.
regards, tom lane
Commits
-
Cope with glibc too old to have epoll_create1().
- 53b157846024 9.6.3 landed
- 82ebbeb0abfe 10.0 landed
-
Make latch.c more paranoid about child-process cases.
- fa31b6f4e969 10.0 landed
- 866452cd8b52 9.6.3 landed
-
Allow multiple bgworkers to be launched per postmaster iteration.
- aa1351f1eec4 10.0 landed
- e880df25ec35 9.6.3 landed
-
Revert "Use pselect(2) not select(2), if available, to wait in postmaster's loop."
- e615605239f6 9.6.3 landed
- 64925603c972 10.0 landed
-
Use pselect(2) not select(2), if available, to wait in postmaster's loop.
- b9515b628797 9.6.3 landed
- 81069a9efc5a 10.0 landed
-
Run the postmaster's signal handlers without SA_RESTART.
- 8939020853e6 10.0 landed
- dfa4baf91cee 9.6.3 landed
-
Fix postmaster's handling of fork failure for a bgworker process.
- dba1f310a564 9.5.7 landed
- 63f64d2824b2 9.6.3 landed
- 4fe04244b584 10.0 landed
- 436b560b86ca 9.4.12 landed
-
Partially revert commit 536d47bd9d5fce8d91929bee3128fa1d08dbcc57.
- 5041cdf2b792 10.0 landed
-
Avoid depending on non-POSIX behavior of fcntl(2).
- 3e51725b3854 10.0 landed
- f07f6b62c9a7 9.6.3 landed
- ce521e50eb56 9.4.12 landed
- ad8fb69cccf4 9.2.21 landed
- 9f8be7542156 9.5.7 landed
- 899960b9fec2 9.3.17 landed
-
Remove long-obsolete catering for platforms without F_SETFD/FD_CLOEXEC.
- 536d47bd9d5f 10.0 landed