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

Commit73f6b9a

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 parent6cf1647 commit73f6b9a

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
@@ -1452,9 +1452,9 @@ WaitEventSetWait(WaitEventSet *set, long timeout,
14521452
intrc;
14531453

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

1502-
break;
1502+
if (returned_events==nevents)
1503+
break;/* output buffer full already */
1504+
1505+
/*
1506+
* Even though we already have an event, we'll poll just once with
1507+
* zero timeout to see what non-latch events we can fit into the
1508+
* output buffer at the same time.
1509+
*/
1510+
cur_timeout=0;
1511+
timeout=0;
15031512
}
15041513

15051514
/*
@@ -1508,18 +1517,16 @@ WaitEventSetWait(WaitEventSet *set, long timeout,
15081517
* to retry, everything >= 1 is the number of returned events.
15091518
*/
15101519
rc=WaitEventSetWaitBlock(set,cur_timeout,
1511-
occurred_events,nevents);
1520+
occurred_events,nevents-returned_events);
15121521

1513-
if (set->latch)
1514-
{
1515-
Assert(set->latch->maybe_sleeping);
1522+
if (set->latch&&
1523+
set->latch->maybe_sleeping)
15161524
set->latch->maybe_sleeping= false;
1517-
}
15181525

15191526
if (rc==-1)
15201527
break;/* timeout occurred */
15211528
else
1522-
returned_events=rc;
1529+
returned_events+=rc;
15231530

15241531
/* If we're not done, update cur_timeout for next iteration */
15251532
if (returned_events==0&&timeout >=0)
@@ -1607,7 +1614,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
16071614
/* Drain the signalfd. */
16081615
drain();
16091616

1610-
if (set->latch&&set->latch->is_set)
1617+
if (set->latch&&set->latch->maybe_sleeping&&set->latch->is_set)
16111618
{
16121619
occurred_events->fd=PGINVALID_SOCKET;
16131620
occurred_events->events=WL_LATCH_SET;
@@ -1766,7 +1773,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
17661773
if (cur_event->events==WL_LATCH_SET&&
17671774
cur_kqueue_event->filter==EVFILT_SIGNAL)
17681775
{
1769-
if (set->latch&&set->latch->is_set)
1776+
if (set->latch&&set->latch->maybe_sleeping&&set->latch->is_set)
17701777
{
17711778
occurred_events->fd=PGINVALID_SOCKET;
17721779
occurred_events->events=WL_LATCH_SET;
@@ -1891,7 +1898,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
18911898
/* There's data in the self-pipe, clear it. */
18921899
drain();
18931900

1894-
if (set->latch&&set->latch->is_set)
1901+
if (set->latch&&set->latch->maybe_sleeping&&set->latch->is_set)
18951902
{
18961903
occurred_events->fd=PGINVALID_SOCKET;
18971904
occurred_events->events=WL_LATCH_SET;
@@ -2107,7 +2114,7 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
21072114
if (!ResetEvent(set->handles[cur_event->pos+1]))
21082115
elog(ERROR,"ResetEvent failed: error code %lu",GetLastError());
21092116

2110-
if (set->latch&&set->latch->is_set)
2117+
if (set->latch&&set->latch->maybe_sleeping&&set->latch->is_set)
21112118
{
21122119
occurred_events->fd=PGINVALID_SOCKET;
21132120
occurred_events->events=WL_LATCH_SET;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp