Remove set_latch_on_sigusr1 flag.
authorRobert Haas <rhaas@postgresql.org>
Fri, 9 Oct 2015 18:31:04 +0000 (14:31 -0400)
committerRobert Haas <rhaas@postgresql.org>
Fri, 9 Oct 2015 18:31:04 +0000 (14:31 -0400)
This flag has proven to be a recipe for bugs, and it doesn't seem like
it can really buy anything in terms of performance.  So let's just
*always* set the process latch when we receive SIGUSR1 instead of
trying to do it only when needed.

Per my recent proposal on pgsql-hackers.

src/backend/postmaster/bgworker.c
src/backend/storage/ipc/procsignal.c
src/backend/storage/ipc/shm_mq.c
src/backend/tcop/postgres.c
src/include/storage/procsignal.h
src/test/modules/test_shm_mq/setup.c

index 68c9505809eaea221efa767198a03f078bae80db..c38d486a20e253cbc1360cdb800da5c61da999d4 100644 (file)
@@ -954,45 +954,31 @@ WaitForBackgroundWorkerStartup(BackgroundWorkerHandle *handle, pid_t *pidp)
 {
    BgwHandleStatus status;
    int         rc;
-   bool        save_set_latch_on_sigusr1;
 
-   save_set_latch_on_sigusr1 = set_latch_on_sigusr1;
-   set_latch_on_sigusr1 = true;
-
-   PG_TRY();
+   for (;;)
    {
-       for (;;)
-       {
-           pid_t       pid;
+       pid_t       pid;
 
-           CHECK_FOR_INTERRUPTS();
+       CHECK_FOR_INTERRUPTS();
 
-           status = GetBackgroundWorkerPid(handle, &pid);
-           if (status == BGWH_STARTED)
-               *pidp = pid;
-           if (status != BGWH_NOT_YET_STARTED)
-               break;
-
-           rc = WaitLatch(MyLatch,
-                          WL_LATCH_SET | WL_POSTMASTER_DEATH, 0);
+       status = GetBackgroundWorkerPid(handle, &pid);
+       if (status == BGWH_STARTED)
+           *pidp = pid;
+       if (status != BGWH_NOT_YET_STARTED)
+           break;
 
-           if (rc & WL_POSTMASTER_DEATH)
-           {
-               status = BGWH_POSTMASTER_DIED;
-               break;
-           }
+       rc = WaitLatch(MyLatch,
+                      WL_LATCH_SET | WL_POSTMASTER_DEATH, 0);
 
-           ResetLatch(MyLatch);
+       if (rc & WL_POSTMASTER_DEATH)
+       {
+           status = BGWH_POSTMASTER_DIED;
+           break;
        }
+
+       ResetLatch(MyLatch);
    }
-   PG_CATCH();
-   {
-       set_latch_on_sigusr1 = save_set_latch_on_sigusr1;
-       PG_RE_THROW();
-   }
-   PG_END_TRY();
 
-   set_latch_on_sigusr1 = save_set_latch_on_sigusr1;
    return status;
 }
 
@@ -1009,40 +995,26 @@ WaitForBackgroundWorkerShutdown(BackgroundWorkerHandle *handle)
 {
    BgwHandleStatus status;
    int         rc;
-   bool        save_set_latch_on_sigusr1;
-
-   save_set_latch_on_sigusr1 = set_latch_on_sigusr1;
-   set_latch_on_sigusr1 = true;
 
-   PG_TRY();
+   for (;;)
    {
-       for (;;)
-       {
-           pid_t       pid;
+       pid_t       pid;
 
-           CHECK_FOR_INTERRUPTS();
+       CHECK_FOR_INTERRUPTS();
 
-           status = GetBackgroundWorkerPid(handle, &pid);
-           if (status == BGWH_STOPPED)
-               return status;
+       status = GetBackgroundWorkerPid(handle, &pid);
+       if (status == BGWH_STOPPED)
+           return status;
 
-           rc = WaitLatch(&MyProc->procLatch,
-                          WL_LATCH_SET | WL_POSTMASTER_DEATH, 0);
+       rc = WaitLatch(&MyProc->procLatch,
+                      WL_LATCH_SET | WL_POSTMASTER_DEATH, 0);
 
-           if (rc & WL_POSTMASTER_DEATH)
-               return BGWH_POSTMASTER_DIED;
+       if (rc & WL_POSTMASTER_DEATH)
+           return BGWH_POSTMASTER_DIED;
 
-           ResetLatch(&MyProc->procLatch);
-       }
-   }
-   PG_CATCH();
-   {
-       set_latch_on_sigusr1 = save_set_latch_on_sigusr1;
-       PG_RE_THROW();
+       ResetLatch(&MyProc->procLatch);
    }
-   PG_END_TRY();
 
-   set_latch_on_sigusr1 = save_set_latch_on_sigusr1;
    return status;
 }
 
index 0abde43565bcc631e12eaf2694671dbe7cbafcfb..acfb4e9be82bf5d70f4031e5e7746ac843736844 100644 (file)
@@ -59,14 +59,6 @@ typedef struct
  */
 #define NumProcSignalSlots (MaxBackends + NUM_AUXPROCTYPES)
 
-/*
- * If this flag is set, the process latch will be set whenever SIGUSR1
- * is received.  This is useful when waiting for a signal from the postmaster.
- * Spurious wakeups must be expected.  Make sure that the flag is cleared
- * in the error path.
- */
-bool       set_latch_on_sigusr1;
-
 static ProcSignalSlot *ProcSignalSlots = NULL;
 static volatile ProcSignalSlot *MyProcSignalSlot = NULL;
 
@@ -296,8 +288,7 @@ procsignal_sigusr1_handler(SIGNAL_ARGS)
    if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN))
        RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN);
 
-   if (set_latch_on_sigusr1)
-       SetLatch(MyLatch);
+   SetLatch(MyLatch);
 
    latch_sigusr1_handler();
 
index c78f1650e6af4eaf741be75448766ce7a09ec03c..80956ce4304ae7db2778876a958922f2aeb9b6af 100644 (file)
@@ -962,63 +962,49 @@ static bool
 shm_mq_wait_internal(volatile shm_mq *mq, PGPROC *volatile * ptr,
                     BackgroundWorkerHandle *handle)
 {
-   bool        save_set_latch_on_sigusr1;
    bool        result = false;
 
-   save_set_latch_on_sigusr1 = set_latch_on_sigusr1;
-   if (handle != NULL)
-       set_latch_on_sigusr1 = true;
-
-   PG_TRY();
+   for (;;)
    {
-       for (;;)
+       BgwHandleStatus status;
+       pid_t       pid;
+       bool        detached;
+
+       /* Acquire the lock just long enough to check the pointer. */
+       SpinLockAcquire(&mq->mq_mutex);
+       detached = mq->mq_detached;
+       result = (*ptr != NULL);
+       SpinLockRelease(&mq->mq_mutex);
+
+       /* Fail if detached; else succeed if initialized. */
+       if (detached)
+       {
+           result = false;
+           break;
+       }
+       if (result)
+           break;
+
+       if (handle != NULL)
        {
-           BgwHandleStatus status;
-           pid_t       pid;
-           bool        detached;
-
-           /* Acquire the lock just long enough to check the pointer. */
-           SpinLockAcquire(&mq->mq_mutex);
-           detached = mq->mq_detached;
-           result = (*ptr != NULL);
-           SpinLockRelease(&mq->mq_mutex);
-
-           /* Fail if detached; else succeed if initialized. */
-           if (detached)
+           /* Check for unexpected worker death. */
+           status = GetBackgroundWorkerPid(handle, &pid);
+           if (status != BGWH_STARTED && status != BGWH_NOT_YET_STARTED)
            {
                result = false;
                break;
            }
-           if (result)
-               break;
-
-           if (handle != NULL)
-           {
-               /* Check for unexpected worker death. */
-               status = GetBackgroundWorkerPid(handle, &pid);
-               if (status != BGWH_STARTED && status != BGWH_NOT_YET_STARTED)
-               {
-                   result = false;
-                   break;
-               }
-           }
+       }
 
-           /* Wait to be signalled. */
-           WaitLatch(MyLatch, WL_LATCH_SET, 0);
+       /* Wait to be signalled. */
+       WaitLatch(MyLatch, WL_LATCH_SET, 0);
 
-           /* An interrupt may have occurred while we were waiting. */
-           CHECK_FOR_INTERRUPTS();
+       /* An interrupt may have occurred while we were waiting. */
+       CHECK_FOR_INTERRUPTS();
 
-           /* Reset the latch so we don't spin. */
-           ResetLatch(MyLatch);
-       }
-   }
-   PG_CATCH();
-   {
-       set_latch_on_sigusr1 = save_set_latch_on_sigusr1;
-       PG_RE_THROW();
+       /* Reset the latch so we don't spin. */
+       ResetLatch(MyLatch);
    }
-   PG_END_TRY();
 
    return result;
 }
index aee13aec757b87aaba93c043ebb7528fb5a66d8a..d30fe35c14fcc00176a8c5594f98537807c7583a 100644 (file)
@@ -2825,9 +2825,7 @@ RecoveryConflictInterrupt(ProcSignalReason reason)
    /*
     * Set the process latch. This function essentially emulates signal
     * handlers like die() and StatementCancelHandler() and it seems prudent
-    * to behave similarly as they do. Alternatively all plain backend code
-    * waiting on that latch, expecting to get interrupted by query cancels et
-    * al., would also need to set set_latch_on_sigusr1.
+    * to behave similarly as they do.
     */
    SetLatch(MyLatch);
 
index af1a0cd71f25b900ed9187b5007203142b858a1d..50ffb13e1f2b7bfcc70aec16a7cbf4b80b23bab8 100644 (file)
@@ -55,6 +55,5 @@ extern int SendProcSignal(pid_t pid, ProcSignalReason reason,
               BackendId backendId);
 
 extern void procsignal_sigusr1_handler(SIGNAL_ARGS);
-extern PGDLLIMPORT bool set_latch_on_sigusr1;
 
 #endif   /* PROCSIGNAL_H */
index 7f2f5fd3ff72efb784c5c399fb43b17ed889465b..dedd72f88385f4f08eb8b6bb82f424750ffa6258 100644 (file)
@@ -255,51 +255,38 @@ static void
 wait_for_workers_to_become_ready(worker_state *wstate,
                                 volatile test_shm_mq_header *hdr)
 {
-   bool        save_set_latch_on_sigusr1;
    bool        result = false;
 
-   save_set_latch_on_sigusr1 = set_latch_on_sigusr1;
-   set_latch_on_sigusr1 = true;
-
-   PG_TRY();
+   for (;;)
    {
-       for (;;)
+       int         workers_ready;
+
+       /* If all the workers are ready, we have succeeded. */
+       SpinLockAcquire(&hdr->mutex);
+       workers_ready = hdr->workers_ready;
+       SpinLockRelease(&hdr->mutex);
+       if (workers_ready >= wstate->nworkers)
        {
-           int         workers_ready;
-
-           /* If all the workers are ready, we have succeeded. */
-           SpinLockAcquire(&hdr->mutex);
-           workers_ready = hdr->workers_ready;
-           SpinLockRelease(&hdr->mutex);
-           if (workers_ready >= wstate->nworkers)
-           {
-               result = true;
-               break;
-           }
-
-           /* If any workers (or the postmaster) have died, we have failed. */
-           if (!check_worker_status(wstate))
-           {
-               result = false;
-               break;
-           }
-
-           /* Wait to be signalled. */
-           WaitLatch(MyLatch, WL_LATCH_SET, 0);
-
-           /* An interrupt may have occurred while we were waiting. */
-           CHECK_FOR_INTERRUPTS();
-
-           /* Reset the latch so we don't spin. */
-           ResetLatch(MyLatch);
+           result = true;
+           break;
        }
+
+       /* If any workers (or the postmaster) have died, we have failed. */
+       if (!check_worker_status(wstate))
+       {
+           result = false;
+           break;
+       }
+
+       /* Wait to be signalled. */
+       WaitLatch(MyLatch, WL_LATCH_SET, 0);
+
+       /* An interrupt may have occurred while we were waiting. */
+       CHECK_FOR_INTERRUPTS();
+
+       /* Reset the latch so we don't spin. */
+       ResetLatch(MyLatch);
    }
-   PG_CATCH();
-   {
-       set_latch_on_sigusr1 = save_set_latch_on_sigusr1;
-       PG_RE_THROW();
-   }
-   PG_END_TRY();
 
    if (!result)
        ereport(ERROR,