Skip to content
This repository was archived by the owner on May 24, 2026. It is now read-only.

Commit c59bd3f

Browse files
caesayclaude
andcommitted
Use InitOnceExecuteOnce for thread-safe CRITICAL_SECTION init
Replace InterlockedCompareExchange (which has a TOCTOU race) with InitOnceExecuteOnce for guaranteed single initialization. Also only suppress G_LOG_LEVEL_CRITICAL (not FATAL) to preserve actual crash diagnostics. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 88f3553 commit c59bd3f

1 file changed

Lines changed: 11 additions & 12 deletions

File tree

msi-interop/handle_table.c

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,20 @@ static gboolean initialized = FALSE;
4242
*/
4343
#ifdef _WIN32
4444
static CRITICAL_SECTION libmsi_cs;
45-
static volatile LONG libmsi_cs_initialized = 0;
4645

47-
static void ensure_cs_initialized(void)
46+
static BOOL CALLBACK init_cs_once(PINIT_ONCE initOnce, PVOID param, PVOID *context)
4847
{
49-
if (InterlockedCompareExchange(&libmsi_cs_initialized, 1, 0) == 0) {
50-
InitializeCriticalSection(&libmsi_cs);
51-
}
48+
(void)initOnce; (void)param; (void)context;
49+
InitializeCriticalSection(&libmsi_cs);
50+
return TRUE;
5251
}
5352

53+
static INIT_ONCE cs_init_once = INIT_ONCE_STATIC_INIT;
54+
5455
void
5556
libmsi_global_lock(void)
5657
{
57-
ensure_cs_initialized();
58+
InitOnceExecuteOnce(&cs_init_once, init_cs_once, NULL, NULL);
5859
EnterCriticalSection(&libmsi_cs);
5960
}
6061

@@ -322,10 +323,8 @@ handle_table_auto_init(void)
322323
g_type_ensure(libmsi_summary_info_get_type());
323324
handle_table_init();
324325

325-
// Suppress GLib critical warnings on stderr during process shutdown.
326-
// .NET finalizers may call MsiCloseHandle after GLib's internal state
327-
// is partially torn down, producing g_object_unref assertion messages
328-
// that cause test runners to detect a "crash".
329-
g_log_set_handler("GLib-GObject", G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL, silent_log_handler, NULL);
330-
g_log_set_handler("GLib", G_LOG_LEVEL_CRITICAL | G_LOG_FLAG_FATAL, silent_log_handler, NULL);
326+
// Suppress GLib critical warnings on stderr that cause test runners
327+
// to detect false "crashes" during process shutdown cleanup.
328+
g_log_set_handler("GLib-GObject", G_LOG_LEVEL_CRITICAL, silent_log_handler, NULL);
329+
g_log_set_handler("GLib", G_LOG_LEVEL_CRITICAL, silent_log_handler, NULL);
331330
}

0 commit comments

Comments
 (0)