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
