On Thu, Jul 2, 2020 at 6:39 PM James Sewell <james.sewell@jirotech.com> wrote:
> The patch replaces sigprocmask with pthread_sigmask. They have identical APIs ("[pthread_sigmask] shall be equivalent
tosigprocmask(), without the restriction that the call be made in a single-threaded process"[1])
-#define PG_SETMASK(mask) sigprocmask(SIG_SETMASK, mask, NULL)
+#define PG_SETMASK(mask) pthread_sigmask(SIG_SETMASK, mask, NULL)
So you're assuming that <signal.h> declares pthread_sigmask(). I was
trying to understand what POSIX's "The functionality described is
optional" means; could there be <signal.h> headers without the
declaration? I mean, I know the practical answer: we support all the
remaining Unixes, you can count them on two hands, and they all have
pthreads, so it doesn't matter, and like Dr Stonebraker said, the plan
is "converting POSTGRES to use lightweight processes available in the
operating systems we are using. These include PRESTO for the Sequent
Symmetry and threads in Version 4 of Sun/OS." so we'll actually
*require* that stuff eventually anyway.
One practical problem with this change is that some systems have a
stub definition of pthread_sigmask() that does nothing, when you don't
link against the threading library. Realistically, most *useful*
builds of PostgreSQL bring it in indirectly (via SSL, LDAP, blah
blah), but it so happens that a bare bones build and make check on
this here FreeBSD box hangs in CHECK DATABASE waiting for the
checkpointer to signal it. I can fix that by putting -lthr into
LDFLAGS, so we'd probably have to figure out how to do that on our
supported systems.
> The rationale here is that as far as I can tell this is the *only* blocker to using multithreaded code in a BGWorker
whichcan't be avoided by adhering to strict code rules (eg: no PG calls from non-main threads, no interaction with
signalsfrom non-main threads).
I guess you'd have to mask at least all the signals we care about
before every call to pthread_create() and trust that the threads never
unmask them. I guess you could interpose a checker function to abort
if something tries to break the programming rule.