274
274
InitLatch (Latch * latch )
275
275
{
276
276
latch -> is_set = false;
277
+ latch -> maybe_sleeping = false;
277
278
latch -> owner_pid = MyProcPid ;
278
279
latch -> is_shared = false;
279
280
@@ -321,6 +322,7 @@ InitSharedLatch(Latch *latch)
321
322
#endif
322
323
323
324
latch -> is_set = false;
325
+ latch -> maybe_sleeping = false;
324
326
latch -> owner_pid = 0 ;
325
327
latch -> is_shared = true;
326
328
}
@@ -523,6 +525,10 @@ SetLatch(Latch *latch)
523
525
524
526
latch -> is_set = true;
525
527
528
+ pg_memory_barrier ();
529
+ if (!latch -> maybe_sleeping )
530
+ return ;
531
+
526
532
#ifndef WIN32
527
533
528
534
/*
@@ -589,6 +595,7 @@ ResetLatch(Latch *latch)
589
595
{
590
596
/* Only the owner should reset the latch */
591
597
Assert (latch -> owner_pid == MyProcPid );
598
+ Assert (latch -> maybe_sleeping == false);
592
599
593
600
latch -> is_set = false;
594
601
@@ -1270,6 +1277,14 @@ WaitEventSetWait(WaitEventSet *set, long timeout,
1270
1277
* ordering, so that we cannot miss seeing is_set if a notification
1271
1278
* has already been queued.
1272
1279
*/
1280
+ if (set -> latch && !set -> latch -> is_set )
1281
+ {
1282
+ /* about to sleep on a latch */
1283
+ set -> latch -> maybe_sleeping = true;
1284
+ pg_memory_barrier ();
1285
+ /* and recheck */
1286
+ }
1287
+
1273
1288
if (set -> latch && set -> latch -> is_set )
1274
1289
{
1275
1290
occurred_events -> fd = PGINVALID_SOCKET ;
@@ -1280,6 +1295,9 @@ WaitEventSetWait(WaitEventSet *set, long timeout,
1280
1295
occurred_events ++ ;
1281
1296
returned_events ++ ;
1282
1297
1298
+ /* could have been set above */
1299
+ set -> latch -> maybe_sleeping = false;
1300
+
1283
1301
break ;
1284
1302
}
1285
1303
@@ -1291,6 +1309,12 @@ WaitEventSetWait(WaitEventSet *set, long timeout,
1291
1309
rc = WaitEventSetWaitBlock (set , cur_timeout ,
1292
1310
occurred_events , nevents );
1293
1311
1312
+ if (set -> latch )
1313
+ {
1314
+ Assert (set -> latch -> maybe_sleeping );
1315
+ set -> latch -> maybe_sleeping = false;
1316
+ }
1317
+
1294
1318
if (rc == -1 )
1295
1319
break ; /* timeout occurred */
1296
1320
else
0 commit comments