]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Allow condition variables to be used in interrupt code.
authorThomas Munro <tmunro@postgresql.org>
Mon, 1 Mar 2021 03:28:12 +0000 (16:28 +1300)
committerThomas Munro <tmunro@postgresql.org>
Mon, 1 Mar 2021 04:24:47 +0000 (17:24 +1300)
Adjust the condition variable sleep loop to work correctly when code
reached by its internal CHECK_FOR_INTERRUPTS() call interacts with
another condition variable.

There are no such cases currently, but a proposed patch would do this.

Discussion: https://postgr.es/m/CA+hUKGLdemy2gBm80kz20GTe6hNVwoErE8KwcJk6-U56oStjtg@mail.gmail.com

src/backend/storage/lmgr/condition_variable.c

index 0a61ff0031fefb83a6395dc525e92e3d1ee9b912..80d70c154cf7c430e2e9c6955f4622462fb96e22 100644 (file)
@@ -165,8 +165,6 @@ ConditionVariableTimedSleep(ConditionVariable *cv, long timeout,
                /* Reset latch before examining the state of the wait list. */
                ResetLatch(MyLatch);
 
-               CHECK_FOR_INTERRUPTS();
-
                /*
                 * If this process has been taken out of the wait list, then we know
                 * that it has been signaled by ConditionVariableSignal (or
@@ -190,6 +188,15 @@ ConditionVariableTimedSleep(ConditionVariable *cv, long timeout,
                }
                SpinLockRelease(&cv->mutex);
 
+               /*
+                * Check for interrupts, and return spuriously if that caused the
+                * current sleep target to change (meaning that interrupt handler code
+                * waited for a different condition variable).
+                */
+               CHECK_FOR_INTERRUPTS();
+               if (cv != cv_sleep_target)
+                       done = true;
+
                /* We were signaled, so return */
                if (done)
                        return false;