Attached is a follow-up to Sehrope's CF7218 timer fix - close each
created alarm-thread handle. Closing the handle leaves the callback
running.

This is a dependent supplement. Apply the included CreateThread
failure-check prerequisite, then this patch, on master 8e82d6610e7.
The prerequisite credits Sehrope; it contains only his timer fix.

Source-extracted probes on native ARM64 and emulated x64 show 200
retained handles before the change and none afterward, with all 200
callbacks completing. The actual pg_test_fsync -s 1 benchmark sequence
also passes on both targets in the combined integration builds.
Formatting and independent reviews pass.

The measurements establish handle cleanup and callback completion;
they aren't performance benchmarks.

Let me know your thoughts.

Best,

Harrison
From 838c698517544fcc4fdcc7a2536a915327354569 Mon Sep 17 00:00:00 2001
From: Sehrope Sarkuni <[email protected]>
Date: Wed, 10 Jun 2026 09:32:14 -0400
Subject: [PATCH] Fix CreateThread failure check in pg_test_fsync

CreateThread returns NULL on failure, not INVALID_HANDLE_VALUE, so
the error branch could never fire.
---
 src/bin/pg_test_fsync/pg_test_fsync.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/bin/pg_test_fsync/pg_test_fsync.c b/src/bin/pg_test_fsync/pg_test_fsync.c
index c51b1271f1f..39d0792614d 100644
--- a/src/bin/pg_test_fsync/pg_test_fsync.c
+++ b/src/bin/pg_test_fsync/pg_test_fsync.c
@@ -50,8 +50,7 @@ do { \
 #define START_TIMER \
 do { \
 	alarm_triggered = false; \
-	if (CreateThread(NULL, 0, process_alarm, NULL, 0, NULL) == \
-		INVALID_HANDLE_VALUE) \
+	if (CreateThread(NULL, 0, process_alarm, NULL, 0, NULL) == NULL) \
 		pg_fatal("could not create thread for alarm"); \
 	gettimeofday(&start_t, NULL); \
 } while (0)
-- 
2.53.0.windows.2

From f669c040f77ac03505a2d2ec46d057f60d426aa0 Mon Sep 17 00:00:00 2001
From: Harrison Booth <[email protected]>
Date: Mon, 12 Oct 2026 20:44:27 -0500
Subject: [PATCH] Close the Windows pg_test_fsync timer thread handle

The timer callback does not need its creator to retain a thread handle.
Close each successfully created handle so successive benchmark phases
do not retain kernel object references until pg_test_fsync exits.

Builds on the separately proposed NULL CreateThread failure check by
Sehrope Sarkuni. Source-extracted timer probes reproduce one leaked
handle per callback on native ARM64 and emulated x64. Closing the handle
leaves all callbacks functional and removes the handle growth.
---
 src/bin/pg_test_fsync/pg_test_fsync.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/bin/pg_test_fsync/pg_test_fsync.c b/src/bin/pg_test_fsync/pg_test_fsync.c
index 39d0792614d..5732d4c0de3 100644
--- a/src/bin/pg_test_fsync/pg_test_fsync.c
+++ b/src/bin/pg_test_fsync/pg_test_fsync.c
@@ -49,9 +49,13 @@ do { \
 /* WIN32 doesn't support alarm, so we create a thread and sleep there */
 #define START_TIMER \
 do { \
+	HANDLE		alarm_thread; \
+\
 	alarm_triggered = false; \
-	if (CreateThread(NULL, 0, process_alarm, NULL, 0, NULL) == NULL) \
+	alarm_thread = CreateThread(NULL, 0, process_alarm, NULL, 0, NULL); \
+	if (alarm_thread == NULL) \
 		pg_fatal("could not create thread for alarm"); \
+	CloseHandle(alarm_thread); \
 	gettimeofday(&start_t, NULL); \
 } while (0)
 #endif
-- 
2.53.0.windows.2

Reply via email to