@@ -43,11 +43,22 @@ ConditionVariableInit(ConditionVariable *cv)
4343}
4444
4545/*
46- * Prepare to wait on a given condition variable. This can optionally be
47- * called before entering a test/sleep loop. Alternatively, the call to
48- * ConditionVariablePrepareToSleep can be omitted. The only advantage of
49- * calling ConditionVariablePrepareToSleep is that it avoids an initial
50- * double-test of the user's predicate in the case that we need to wait.
46+ * Prepare to wait on a given condition variable.
47+ *
48+ * This can optionally be called before entering a test/sleep loop.
49+ * Doing so is more efficient if we'll need to sleep at least once.
50+ * However, if the first test of the exit condition is likely to succeed,
51+ * it's more efficient to omit the ConditionVariablePrepareToSleep call.
52+ * See comments in ConditionVariableSleep for more detail.
53+ *
54+ * Caution: "before entering the loop" means you *must* test the exit
55+ * condition between calling ConditionVariablePrepareToSleep and calling
56+ * ConditionVariableSleep. If that is inconvenient, omit calling
57+ * ConditionVariablePrepareToSleep.
58+ *
59+ * Only one condition variable can be used at a time, ie,
60+ * ConditionVariableCancelSleep must be called before any attempt is made
61+ * to sleep on a different condition variable.
5162 */
5263void
5364ConditionVariablePrepareToSleep (ConditionVariable * cv )
@@ -79,8 +90,8 @@ ConditionVariablePrepareToSleep(ConditionVariable *cv)
7990cv_sleep_target = cv ;
8091
8192/*
82- * Reset my latch before adding myself to the queue and before entering
83- *the caller's predicate loop .
93+ * Reset my latch before adding myself to the queue, to ensure that we
94+ *don't miss a wakeup that occurs immediately .
8495 */
8596ResetLatch (MyLatch );
8697
@@ -90,20 +101,21 @@ ConditionVariablePrepareToSleep(ConditionVariable *cv)
90101SpinLockRelease (& cv -> mutex );
91102}
92103
93- /*--------------------------------------------------------------------------
94- * Wait for the given condition variable to be signaled. This should be
95- * called in a predicate loop that tests for a specific exit condition and
96- * otherwise sleeps, like so:
104+ /*
105+ * Wait for the given condition variable to be signaled.
106+ *
107+ * This should be called in a predicate loop that tests for a specific exit
108+ * condition and otherwise sleeps, like so:
97109 *
98- * ConditionVariablePrepareToSleep(cv);[ optional]
110+ * ConditionVariablePrepareToSleep(cv); // optional
99111 * while (condition for which we are waiting is not true)
100112 * ConditionVariableSleep(cv, wait_event_info);
101113 * ConditionVariableCancelSleep();
102114 *
103- *Supply a value from one of the WaitEventXXX enums defined in pgstat.h to
104- *control the contents of pg_stat_activity's wait_event_type and wait_event
105- * columns while waiting.
106- *-------------------------------------------------------------------------* /
115+ *wait_event_info should be a value from one of the WaitEventXXX enums
116+ *defined in pgstat.h. This controls the contents of pg_stat_activity's
117+ *wait_event_type and wait_event columns while waiting.
118+ */
107119void
108120ConditionVariableSleep (ConditionVariable * cv ,uint32 wait_event_info )
109121{
@@ -113,13 +125,14 @@ ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info)
113125/*
114126 * If the caller didn't prepare to sleep explicitly, then do so now and
115127 * return immediately. The caller's predicate loop should immediately
116- * call again if its exit condition is not yet met. This initial spurious
117- * return can be avoided by calling ConditionVariablePrepareToSleep(cv)
128+ * call again if its exit condition is not yet met. This will result in
129+ * the exit condition being tested twice before we first sleep. The extra
130+ * test can be prevented by calling ConditionVariablePrepareToSleep(cv)
118131 * first. Whether it's worth doing that depends on whether you expect the
119- * condition to be met initially, in which case skipping the prepare
120- *allows you to skip manipulation of the wait list, or not met initially,
121- * in which case preparing firstallows you to skip a spurious test of the
122- *caller's exit condition.
132+ *exit condition to be met initially, in which case skipping the prepare
133+ *is recommended because it avoids manipulations of the wait list, or not
134+ *met initially, in which case preparing firstis better because it
135+ *avoids one extra test of the exit condition.
123136 */
124137if (cv_sleep_target == NULL )
125138{
@@ -130,7 +143,7 @@ ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info)
130143/* Any earlier condition variable sleep must have been canceled. */
131144Assert (cv_sleep_target == cv );
132145
133- while (! done )
146+ do
134147{
135148CHECK_FOR_INTERRUPTS ();
136149
@@ -140,18 +153,23 @@ ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info)
140153 */
141154WaitEventSetWait (cv_wait_event_set ,-1 ,& event ,1 ,wait_event_info );
142155
143- /* Reset latch beforetesting whether we can return . */
156+ /* Reset latch beforeexamining the state of the wait list . */
144157ResetLatch (MyLatch );
145158
146159/*
147160 * If this process has been taken out of the wait list, then we know
148- * that is has been signaled by ConditionVariableSignal. We put it
149- * back into the wait list, so we don't miss any further signals while
150- * the caller's loop checks its condition. If it hasn't been taken
151- * out of the wait list, then the latch must have been set by
152- * something other than ConditionVariableSignal; though we don't
153- * guarantee not to return spuriously, we'll avoid these obvious
154- * cases.
161+ * that it has been signaled by ConditionVariableSignal (or
162+ * ConditionVariableBroadcast), so we should return to the caller. But
163+ * that doesn't guarantee that the exit condition is met, only that we
164+ * ought to check it. So we must put the process back into the wait
165+ * list, to ensure we don't miss any additional wakeup occurring while
166+ * the caller checks its exit condition. We can take ourselves out of
167+ * the wait list only when the caller calls
168+ * ConditionVariableCancelSleep.
169+ *
170+ * If we're still in the wait list, then the latch must have been set
171+ * by something other than ConditionVariableSignal; though we don't
172+ * guarantee not to return spuriously, we'll avoid this obvious case.
155173 */
156174SpinLockAcquire (& cv -> mutex );
157175if (!proclist_contains (& cv -> wakeup ,MyProc -> pgprocno ,cvWaitLink ))
@@ -160,13 +178,17 @@ ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info)
160178proclist_push_tail (& cv -> wakeup ,MyProc -> pgprocno ,cvWaitLink );
161179}
162180SpinLockRelease (& cv -> mutex );
163- }
181+ }while (! done );
164182}
165183
166184/*
167- * Cancel any pending sleep operation. We just need to remove ourselves
168- * from the wait queue of any condition variable for which we have previously
169- * prepared a sleep.
185+ * Cancel any pending sleep operation.
186+ *
187+ * We just need to remove ourselves from the wait queue of any condition
188+ * variable for which we have previously prepared a sleep.
189+ *
190+ * Do nothing if nothing is pending; this allows this function to be called
191+ * during transaction abort to clean up any unfinished CV sleep.
170192 */
171193void
172194ConditionVariableCancelSleep (void )