+2024-05-30 Bruno Haible <bruno@clisp.org>
+
+ windows-once: Free allocated resources when done.
+ Based on an observation regarding Cygwin's pthread_once implementation
+ by Takashi Yano <takashi.yano@nifty.ne.jp> at
+ <https://cygwin.com/pipermail/cygwin/2024-January/255182.html> and
+ <https://cygwin.com/pipermail/cygwin-patches/2024q1/012600.html>
+ * lib/windows-once.h (glwthread_once_t): Add field 'num_threads'.
+ (GLWTHREAD_ONCE_INIT): Initialize it to zero.
+ * lib/windows-once.c (glwthread_once): Increment num_threads while the
+ thread uses the lock. Let the last thread that uses the lock destroy it.
+
2024-05-29 Bruno Haible <bruno@clisp.org>
call_once tests: Fix link error on mingw.
{
if (once_control->inited <= 0)
{
+ InterlockedIncrement (&once_control->num_threads);
if (InterlockedIncrement (&once_control->started) == 0)
{
/* This thread is the first one to come to this once_control. */
abort ();
}
}
+ /* Here once_control->inited > 0. */
+ if (InterlockedDecrement (&once_control->num_threads) == 0)
+ /* once_control->num_threads is now zero, and once_control->inited is 1.
+ No other thread will need to use the lock.
+ We can therefore destroy the lock, to free resources. */
+ DeleteCriticalSection (&once_control->lock);
}
}
typedef struct
{
volatile int inited;
+ volatile LONG num_threads;
volatile LONG started;
CRITICAL_SECTION lock;
}
glwthread_once_t;
-#define GLWTHREAD_ONCE_INIT { -1, -1 }
+#define GLWTHREAD_ONCE_INIT { -1, 0, -1 }
#ifdef __cplusplus
extern "C" {