sigdelset(&StartupBlockSig, SIGALRM);
 #endif
 }
+
+/*
+ * Set up a postmaster signal handler for signal "signo"
+ *
+ * Returns the previous handler.
+ *
+ * This is used only in the postmaster, which has its own odd approach to
+ * signal handling.  For signals with handlers, we block all signals for the
+ * duration of signal handler execution.  We also do not set the SA_RESTART
+ * flag; this should be safe given the tiny range of code in which the
+ * postmaster ever unblocks signals.
+ *
+ * pqinitmask() must have been invoked previously.
+ *
+ * On Windows, this function is just an alias for pqsignal()
+ * (and note that it's calling the code in src/backend/port/win32/signal.c,
+ * not src/port/pqsignal.c).  On that platform, the postmaster's signal
+ * handlers still have to block signals for themselves.
+ */
+pqsigfunc
+pqsignal_pm(int signo, pqsigfunc func)
+{
+#ifndef WIN32
+   struct sigaction act,
+               oact;
+
+   act.sa_handler = func;
+   if (func == SIG_IGN || func == SIG_DFL)
+   {
+       /* in these cases, act the same as pqsignal() */
+       sigemptyset(&act.sa_mask);
+       act.sa_flags = SA_RESTART;
+   }
+   else
+   {
+       act.sa_mask = BlockSig;
+       act.sa_flags = 0;
+   }
+#ifdef SA_NOCLDSTOP
+   if (signo == SIGCHLD)
+       act.sa_flags |= SA_NOCLDSTOP;
+#endif
+   if (sigaction(signo, &act, &oact) < 0)
+       return SIG_ERR;
+   return oact.sa_handler;
+#else                          /* WIN32 */
+   return pqsignal(signo, func);
+#endif
+}
 
    /*
     * Set up signal handlers for the postmaster process.
     *
-    * In the postmaster, we want to install non-ignored handlers *without*
-    * SA_RESTART.  This is because they'll be blocked at all times except
-    * when ServerLoop is waiting for something to happen, and during that
-    * window, we want signals to exit the select(2) wait so that ServerLoop
-    * can respond if anything interesting happened.  On some platforms,
-    * signals marked SA_RESTART would not cause the select() wait to end.
-    * Child processes will generally want SA_RESTART, but we expect them to
-    * set up their own handlers before unblocking signals.
+    * In the postmaster, we use pqsignal_pm() rather than pqsignal() (which
+    * is used by all child processes and client processes).  That has a
+    * couple of special behaviors:
+    *
+    * 1. Except on Windows, we tell sigaction() to block all signals for the
+    * duration of the signal handler.  This is faster than our old approach
+    * of blocking/unblocking explicitly in the signal handler, and it should
+    * also prevent excessive stack consumption if signals arrive quickly.
+    *
+    * 2. We do not set the SA_RESTART flag.  This is because signals will be
+    * blocked at all times except when ServerLoop is waiting for something to
+    * happen, and during that window, we want signals to exit the select(2)
+    * wait so that ServerLoop can respond if anything interesting happened.
+    * On some platforms, signals marked SA_RESTART would not cause the
+    * select() wait to end.
+    *
+    * Child processes will generally want SA_RESTART, so pqsignal() sets that
+    * flag.  We expect children to set up their own handlers before
+    * unblocking signals.
     *
     * CAUTION: when changing this list, check for side-effects on the signal
     * handling setup of child processes.  See tcop/postgres.c,
    pqinitmask();
    PG_SETMASK(&BlockSig);
 
-   pqsignal_no_restart(SIGHUP, SIGHUP_handler);    /* reread config file and
-                                                    * have children do same */
-   pqsignal_no_restart(SIGINT, pmdie); /* send SIGTERM and shut down */
-   pqsignal_no_restart(SIGQUIT, pmdie);    /* send SIGQUIT and die */
-   pqsignal_no_restart(SIGTERM, pmdie);    /* wait for children and shut down */
-   pqsignal(SIGALRM, SIG_IGN); /* ignored */
-   pqsignal(SIGPIPE, SIG_IGN); /* ignored */
-   pqsignal_no_restart(SIGUSR1, sigusr1_handler);  /* message from child
-                                                    * process */
-   pqsignal_no_restart(SIGUSR2, dummy_handler);    /* unused, reserve for
-                                                    * children */
-   pqsignal_no_restart(SIGCHLD, reaper);   /* handle child termination */
-   pqsignal(SIGTTIN, SIG_IGN); /* ignored */
-   pqsignal(SIGTTOU, SIG_IGN); /* ignored */
+   pqsignal_pm(SIGHUP, SIGHUP_handler);    /* reread config file and have
+                                            * children do same */
+   pqsignal_pm(SIGINT, pmdie); /* send SIGTERM and shut down */
+   pqsignal_pm(SIGQUIT, pmdie);    /* send SIGQUIT and die */
+   pqsignal_pm(SIGTERM, pmdie);    /* wait for children and shut down */
+   pqsignal_pm(SIGALRM, SIG_IGN);  /* ignored */
+   pqsignal_pm(SIGPIPE, SIG_IGN);  /* ignored */
+   pqsignal_pm(SIGUSR1, sigusr1_handler);  /* message from child process */
+   pqsignal_pm(SIGUSR2, dummy_handler);    /* unused, reserve for children */
+   pqsignal_pm(SIGCHLD, reaper);   /* handle child termination */
+   pqsignal_pm(SIGTTIN, SIG_IGN);  /* ignored */
+   pqsignal_pm(SIGTTOU, SIG_IGN);  /* ignored */
    /* ignore SIGXFSZ, so that ulimit violations work like disk full */
 #ifdef SIGXFSZ
-   pqsignal(SIGXFSZ, SIG_IGN); /* ignored */
+   pqsignal_pm(SIGXFSZ, SIG_IGN);  /* ignored */
 #endif
 
    /*
 {
    int         save_errno = errno;
 
+   /*
+    * We rely on the signal mechanism to have blocked all signals ... except
+    * on Windows, which lacks sigaction(), so we have to do it manually.
+    */
+#ifdef WIN32
    PG_SETMASK(&BlockSig);
+#endif
 
    if (Shutdown <= SmartShutdown)
    {
 #endif
    }
 
+#ifdef WIN32
    PG_SETMASK(&UnBlockSig);
+#endif
 
    errno = save_errno;
 }
 {
    int         save_errno = errno;
 
+   /*
+    * We rely on the signal mechanism to have blocked all signals ... except
+    * on Windows, which lacks sigaction(), so we have to do it manually.
+    */
+#ifdef WIN32
    PG_SETMASK(&BlockSig);
+#endif
 
    ereport(DEBUG2,
            (errmsg_internal("postmaster received signal %d",
            break;
    }
 
+#ifdef WIN32
    PG_SETMASK(&UnBlockSig);
+#endif
 
    errno = save_errno;
 }
    int         pid;            /* process id of dead child process */
    int         exitstatus;     /* its exit status */
 
+   /*
+    * We rely on the signal mechanism to have blocked all signals ... except
+    * on Windows, which lacks sigaction(), so we have to do it manually.
+    */
+#ifdef WIN32
    PG_SETMASK(&BlockSig);
+#endif
 
    ereport(DEBUG4,
            (errmsg_internal("reaping dead processes")));
    PostmasterStateMachine();
 
    /* Done with signal handler */
+#ifdef WIN32
    PG_SETMASK(&UnBlockSig);
+#endif
 
    errno = save_errno;
 }
 {
    int         save_errno = errno;
 
+   /*
+    * We rely on the signal mechanism to have blocked all signals ... except
+    * on Windows, which lacks sigaction(), so we have to do it manually.
+    */
+#ifdef WIN32
    PG_SETMASK(&BlockSig);
+#endif
 
    /* Process background worker state change. */
    if (CheckPostmasterSignal(PMSIGNAL_BACKGROUND_WORKER_CHANGE))
        signal_child(StartupPID, SIGUSR2);
    }
 
+#ifdef WIN32
    PG_SETMASK(&UnBlockSig);
+#endif
 
    errno = save_errno;
 }