Skip to content

Commit e79ceaf

Browse files
author
Etsuro Fujita
committed
Fix WaitEventSet resource leak in WaitLatchOrSocket().
This function would have the same issue we solved in commit 501cfd0: If an error is thrown after calling CreateWaitEventSet(), the file descriptor (on epoll- or kqueue-based systems) or handles (on Windows) that the WaitEventSet contains are leaked. Like that commit, use PG_TRY-PG_FINALLY (PG_TRY-PG_CATCH in v12) to make sure the WaitEventSet is freed properly. Back-patch to all supported versions, but as we do not have this issue in HEAD (cf. commit 50c67c2), no need to apply this patch to it. Discussion: https://postgr.es/m/CAPmGK16MqdDoD8oatp8SQWaEa4vS3nfQqDN_Sj9YRuu5J3Lj9g%40mail.gmail.com
1 parent 574c7c7 commit e79ceaf

File tree

1 file changed

+38
-32
lines changed

1 file changed

+38
-32
lines changed

src/backend/storage/ipc/latch.c

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -545,48 +545,54 @@ WaitLatchOrSocket(Latch *latch, int wakeEvents, pgsocket sock,
545545
WaitEvent event;
546546
WaitEventSet *set = CreateWaitEventSet(CurrentMemoryContext, 3);
547547

548-
if (wakeEvents & WL_TIMEOUT)
549-
Assert(timeout >= 0);
550-
else
551-
timeout = -1;
548+
PG_TRY();
549+
{
550+
if (wakeEvents & WL_TIMEOUT)
551+
Assert(timeout >= 0);
552+
else
553+
timeout = -1;
552554

553-
if (wakeEvents & WL_LATCH_SET)
554-
AddWaitEventToSet(set, WL_LATCH_SET, PGINVALID_SOCKET,
555-
latch, NULL);
555+
if (wakeEvents & WL_LATCH_SET)
556+
AddWaitEventToSet(set, WL_LATCH_SET, PGINVALID_SOCKET,
557+
latch, NULL);
556558

557-
/* Postmaster-managed callers must handle postmaster death somehow. */
558-
Assert(!IsUnderPostmaster ||
559-
(wakeEvents & WL_EXIT_ON_PM_DEATH) ||
560-
(wakeEvents & WL_POSTMASTER_DEATH));
559+
/* Postmaster-managed callers must handle postmaster death somehow. */
560+
Assert(!IsUnderPostmaster ||
561+
(wakeEvents & WL_EXIT_ON_PM_DEATH) ||
562+
(wakeEvents & WL_POSTMASTER_DEATH));
561563

562-
if ((wakeEvents & WL_POSTMASTER_DEATH) && IsUnderPostmaster)
563-
AddWaitEventToSet(set, WL_POSTMASTER_DEATH, PGINVALID_SOCKET,
564-
NULL, NULL);
564+
if ((wakeEvents & WL_POSTMASTER_DEATH) && IsUnderPostmaster)
565+
AddWaitEventToSet(set, WL_POSTMASTER_DEATH, PGINVALID_SOCKET,
566+
NULL, NULL);
565567

566-
if ((wakeEvents & WL_EXIT_ON_PM_DEATH) && IsUnderPostmaster)
567-
AddWaitEventToSet(set, WL_EXIT_ON_PM_DEATH, PGINVALID_SOCKET,
568-
NULL, NULL);
568+
if ((wakeEvents & WL_EXIT_ON_PM_DEATH) && IsUnderPostmaster)
569+
AddWaitEventToSet(set, WL_EXIT_ON_PM_DEATH, PGINVALID_SOCKET,
570+
NULL, NULL);
569571

570-
if (wakeEvents & WL_SOCKET_MASK)
571-
{
572-
int ev;
572+
if (wakeEvents & WL_SOCKET_MASK)
573+
{
574+
int ev;
573575

574-
ev = wakeEvents & WL_SOCKET_MASK;
575-
AddWaitEventToSet(set, ev, sock, NULL, NULL);
576-
}
576+
ev = wakeEvents & WL_SOCKET_MASK;
577+
AddWaitEventToSet(set, ev, sock, NULL, NULL);
578+
}
577579

578-
rc = WaitEventSetWait(set, timeout, &event, 1, wait_event_info);
580+
rc = WaitEventSetWait(set, timeout, &event, 1, wait_event_info);
579581

580-
if (rc == 0)
581-
ret |= WL_TIMEOUT;
582-
else
582+
if (rc == 0)
583+
ret |= WL_TIMEOUT;
584+
else
585+
{
586+
ret |= event.events & (WL_LATCH_SET |
587+
WL_POSTMASTER_DEATH |
588+
WL_SOCKET_MASK);
589+
}
590+
}
591+
PG_FINALLY();
583592
{
584-
ret |= event.events & (WL_LATCH_SET |
585-
WL_POSTMASTER_DEATH |
586-
WL_SOCKET_MASK);
593+
FreeWaitEventSet(set);
587594
}
588-
589-
FreeWaitEventSet(set);
595+
PG_END_TRY();
590596

591597
return ret;
592598
}

0 commit comments

Comments
 (0)