From 0a22878b8a79347e77f82449a84e93c7ca78ecb9 Mon Sep 17 00:00:00 2001 From: Sami Imseih Date: Fri, 28 Jun 2024 14:40:12 -0500 Subject: [PATCH 1/1] Handle Sleep interrupts --- src/backend/commands/vacuum.c | 2 +- src/backend/port/win32/signal.c | 8 +++++++- src/include/port.h | 1 + src/port/pgsleep.c | 14 +++++++++++++- 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 48f8eab202..b53d137bf5 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2384,7 +2384,7 @@ vacuum_delay_point(void) msec = vacuum_cost_delay * 4; pgstat_report_wait_start(WAIT_EVENT_VACUUM_DELAY); - pg_usleep(msec * 1000); + pg_usleep_handle_interrupt(msec * 1000, true); pgstat_report_wait_end(); /* diff --git a/src/backend/port/win32/signal.c b/src/backend/port/win32/signal.c index 285cb611b4..b7a26b5eb5 100644 --- a/src/backend/port/win32/signal.c +++ b/src/backend/port/win32/signal.c @@ -52,7 +52,13 @@ static BOOL WINAPI pg_console_handler(DWORD dwCtrlType); void pg_usleep(long microsec) { - if (unlikely(pgwin32_signal_event == NULL)) + pg_usleep_handle_interrupt(microsec, false); +} + +void +pg_usleep_handle_interrupt(long microsec, bool force) +{ + if (unlikely(pgwin32_signal_event == NULL) || force) { /* * If we're reached by pgwin32_open_handle() early in startup before diff --git a/src/include/port.h b/src/include/port.h index ae115d2d97..b6b74d05e8 100644 --- a/src/include/port.h +++ b/src/include/port.h @@ -162,6 +162,7 @@ extern int pg_disable_aslr(void); /* Portable delay handling */ extern void pg_usleep(long microsec); +extern void pg_usleep_handle_interrupt(long microsec, bool force); /* Portable SQL-like case-independent comparisons and conversions */ extern int pg_strcasecmp(const char *s1, const char *s2); diff --git a/src/port/pgsleep.c b/src/port/pgsleep.c index 1284458bfc..b45729e219 100644 --- a/src/port/pgsleep.c +++ b/src/port/pgsleep.c @@ -39,15 +39,27 @@ */ void pg_usleep(long microsec) +{ + pg_usleep_handle_interrupt(microsec, false); +} + +void +pg_usleep_handle_interrupt(long microsec, bool force) { if (microsec > 0) { #ifndef WIN32 struct timespec delay; + struct timespec remaining; delay.tv_sec = microsec / 1000000L; delay.tv_nsec = (microsec % 1000000L) * 1000; - (void) nanosleep(&delay, NULL); + + if (force) + while (nanosleep(&delay, &remaining) == -1 && errno == EINTR) + delay = remaining; + else + (void) nanosleep(&delay, NULL); #else SleepEx((microsec < 500 ? 1 : (microsec + 500) / 1000), FALSE); #endif -- 2.39.3 (Apple Git-146)