From: Bruno Haible Date: Sat, 1 Jun 2024 00:31:25 +0000 (+0200) Subject: windows-once: Improve comments. X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=5e7d2073e0ebb0d9ba059951549a66c75a5bef37;p=gnulib.git windows-once: Improve comments. * lib/windows-once.c (glwthread_once): Mention the 'started' field in the comments. --- diff --git a/ChangeLog b/ChangeLog index 85fc1de073..8e09876ea0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2024-05-31 Bruno Haible + + windows-once: Improve comments. + * lib/windows-once.c (glwthread_once): Mention the 'started' field in + the comments. + 2024-05-30 Bruno Haible assert-h, verify: Fix compilation error with g++ (4.8.5) -std=gnu++11. diff --git a/lib/windows-once.c b/lib/windows-once.c index 4d234e0bf2..a8b9e0f3ae 100644 --- a/lib/windows-once.c +++ b/lib/windows-once.c @@ -58,9 +58,10 @@ glwthread_once (glwthread_once_t *once_control, void (*initfunction) (void)) abort (); } } - /* Here once_control->inited > 0. */ + /* Here once_control->started == 0 and once_control->inited > 0. */ if (InterlockedDecrement (&once_control->num_threads) == 0) - /* once_control->num_threads is now zero, and once_control->inited > 0. + /* once_control->num_threads is now zero, and + once_control->started == 0 and once_control->inited > 0. No other thread will need to use the lock. We can therefore destroy the lock, to free resources. */ /* If once_control->inited is == 1, set it to 2. */ @@ -73,15 +74,16 @@ glwthread_once (glwthread_once_t *once_control, void (*initfunction) (void)) * The first thread to go through the once_control->started fence initializes the lock and moves inited from <= 0 to > 0. The other threads don't move inited from <= 0 to > 0. + * started, once == 0, stays == 0. * inited, once > 0, stays > 0 (since at the place where it is assigned 0, it cannot be > 0). * inited does not change any more once it is 2. Therefore, it can be changed from 1 to 2 only once. * DeleteCriticalSection gets invoked right after inited has been changed from 1 to 2. Therefore, DeleteCriticalSection gets invoked only once. - * After a moment where num_threads was 0 and inited was > 0, no thread can - reach an InitializeCriticalSection or EnterCriticalSection invocation. - Proof: + * After a moment where num_threads was 0 and started was 0 and + inited was > 0, no thread can reach an InitializeCriticalSection or + EnterCriticalSection invocation. Proof: - At such a moment, no thread is in the code range between InterlockedIncrement (&once_control->num_threads) and @@ -96,7 +98,7 @@ glwthread_once (glwthread_once_t *once_control, void (*initfunction) (void)) * From this it follows that: - DeleteCriticalSection cannot be executed while the lock is taken (because DeleteCriticalSection is only executed after a moment where - num_threads was 0 and inited was > 0). + num_threads was 0 and started was 0 and inited was > 0). - Once DeleteCriticalSection has been executed, the lock is not used any more. */