From 0a22878b8a79347e77f82449a84e93c7ca78ecb9 Mon Sep 17 00:00:00 2001
From: Sami Imseih <simseih@amazon.com>
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)

