Takashi Yano wrote: > > My workaround implementation of pthread_once (in gnulib) looks like this: > > > > /* This would be the code, for > > typedef struct > > { > > pthread_mutex_t mutex; > > _Atomic unsigned int num_threads; > > _Atomic unsigned int done; > > } > > pthread_once_t; > > */ > > if (once_control->done == 0) > > { > > once_control->num_threads += 1; > > pthread_mutex_lock (&once_control->mutex); > > if (once_control->done == 0) > > { > > (*initfunction) (); > > once_control->done = 1; > > } > > pthread_mutex_unlock (&once_control->mutex); > > if ((once_control->num_threads -= 1) == 0) > > pthread_mutex_destroy (&once_control->mutex); > > } > > > > It makes sure that > > - The last thread that had been dealing with the mutex deletes > > the mutex. > > - Once the mutex is deleted, is it never again accessed. The > > entry test of the 'done' boolean ensures this. > > Thanks for the advice. > > The problem is that we cannot change the type of pthread_once_t > for binary compatibility. My patch stops to use > pthread_mutex_t mutex in pthread_once_t however it cannot be > deleted despite it is not used at all.
This problem can be solved, by using - the upper 31 bits of 'state' as 'num_threads' and - the lowest bit of 'state' as 'done' bit. I did this in gnulib: https://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=blob;f=lib/pthread-once.c;h=069e77e3f3fc2a6e6564f73ba1a3f86ddf9ba531;hb=HEAD#l41 and I have tested it with the test program 'test-pthread-once2' that I mentioned in my original report. You can take this code, since I licensed it under LGPLv2+. You can also surely simplify it, since you are an expert with the Interlocked* atomic operations (whereas I only wanted to use the GCC built-in __sync* atomics). Bruno -- Problem reports: https://cygwin.com/problems.html FAQ: https://cygwin.com/faq/ Documentation: https://cygwin.com/docs.html Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple