Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit44f400f

Browse files
committed
Fix latch event policy that hid socket events.
If a WaitEventSetWait() caller asks for multiple events, an already setlatch would previously prevent other events from being reported at thesame time. Now, we'll also poll the kernel for other events that wouldfit in the caller's output buffer with a zero wait time. This policychange doesn't affect callers that ask for only one event.The main caller affected is the postmaster. If its latch is setextremely frequently by backends launching workers and workers exiting,we don't want it to handle only those jobs and ignore incoming clientconnections.Back-patch to 16 where the postmaster began using the API. Thefast-return policy changed here is older than that, but doesn't causeany known problems in earlier releases.Reported-by: Nathan Bossart <nathandbossart@gmail.com>Reviewed-by: Nathan Bossart <nathandbossart@gmail.com>Discussion:https://postgr.es/m/Z1n5UpAiGDmFcMmd%40nathan
1 parente6767c0 commit44f400f

File tree

1 file changed

+21
-14
lines changed

1 file changed

+21
-14
lines changed

‎src/backend/storage/ipc/latch.c

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,9 +1458,9 @@ WaitEventSetWait(WaitEventSet *set, long timeout,
14581458
intrc;
14591459

14601460
/*
1461-
* Check if the latch is set already.If so,leave the loop
1462-
* immediately, avoid blocking again. We don't attempt to report any
1463-
*other events that might also be satisfied.
1461+
* Check if the latch is set already first.If so,we either exit
1462+
* immediately or ask the kernel for further events available right
1463+
*now without waiting, depending on how many events the caller wants.
14641464
*
14651465
* If someone sets the latch between this and the
14661466
* WaitEventSetWaitBlock() below, the setter will write a byte to the
@@ -1505,7 +1505,16 @@ WaitEventSetWait(WaitEventSet *set, long timeout,
15051505
/* could have been set above */
15061506
set->latch->maybe_sleeping= false;
15071507

1508-
break;
1508+
if (returned_events==nevents)
1509+
break;/* output buffer full already */
1510+
1511+
/*
1512+
* Even though we already have an event, we'll poll just once with
1513+
* zero timeout to see what non-latch events we can fit into the
1514+
* output buffer at the same time.
1515+
*/
1516+
cur_timeout=0;
1517+
timeout=0;
15091518
}
15101519

15111520
/*
@@ -1514,18 +1523,16 @@ WaitEventSetWait(WaitEventSet *set, long timeout,
15141523
* to retry, everything >= 1 is the number of returned events.
15151524
*/
15161525
rc=WaitEventSetWaitBlock(set,cur_timeout,
1517-
occurred_events,nevents);
1526+
occurred_events,nevents-returned_events);
15181527

1519-
if (set->latch)
1520-
{
1521-
Assert(set->latch->maybe_sleeping);
1528+
if (set->latch&&
1529+
set->latch->maybe_sleeping)
15221530
set->latch->maybe_sleeping= false;
1523-
}
15241531

15251532
if (rc==-1)
15261533
break;/* timeout occurred */
15271534
else
1528-
returned_events=rc;
1535+
returned_events+=rc;
15291536

15301537
/* If we're not done, update cur_timeout for next iteration */
15311538
if (returned_events==0&&timeout >=0)
@@ -1613,7 +1620,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
16131620
/* Drain the signalfd. */
16141621
drain();
16151622

1616-
if (set->latch&&set->latch->is_set)
1623+
if (set->latch&&set->latch->maybe_sleeping&&set->latch->is_set)
16171624
{
16181625
occurred_events->fd=PGINVALID_SOCKET;
16191626
occurred_events->events=WL_LATCH_SET;
@@ -1772,7 +1779,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
17721779
if (cur_event->events==WL_LATCH_SET&&
17731780
cur_kqueue_event->filter==EVFILT_SIGNAL)
17741781
{
1775-
if (set->latch&&set->latch->is_set)
1782+
if (set->latch&&set->latch->maybe_sleeping&&set->latch->is_set)
17761783
{
17771784
occurred_events->fd=PGINVALID_SOCKET;
17781785
occurred_events->events=WL_LATCH_SET;
@@ -1897,7 +1904,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
18971904
/* There's data in the self-pipe, clear it. */
18981905
drain();
18991906

1900-
if (set->latch&&set->latch->is_set)
1907+
if (set->latch&&set->latch->maybe_sleeping&&set->latch->is_set)
19011908
{
19021909
occurred_events->fd=PGINVALID_SOCKET;
19031910
occurred_events->events=WL_LATCH_SET;
@@ -2113,7 +2120,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
21132120
if (!ResetEvent(set->handles[cur_event->pos+1]))
21142121
elog(ERROR,"ResetEvent failed: error code %lu",GetLastError());
21152122

2116-
if (set->latch&&set->latch->is_set)
2123+
if (set->latch&&set->latch->maybe_sleeping&&set->latch->is_set)
21172124
{
21182125
occurred_events->fd=PGINVALID_SOCKET;
21192126
occurred_events->events=WL_LATCH_SET;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp