On Thu, 30 May 2024 20:50:12 +0900 Takashi Yano <takashi.y...@nifty.ne.jp> wrote: > On Thu, 30 May 2024 12:14:10 +0200 > Bruno Haible wrote: > > Takashi Yano wrote in cygwin-patches: > > > int > > > pthread::once (pthread_once_t *once_control, void (*init_routine) (void)) > > > { > > > - // already done ? > > > - if (once_control->state) > > > + /* Sign bit of once_control->state is used as done flag */ > > > + if (once_control->state & INT_MIN) > > > return 0; > > > > > > + /* The type of &once_control->state is int *, which is compatible with > > > + LONG * (the type of the first argument of InterlockedIncrement()). > > > */ > > > + InterlockedIncrement (&once_control->state); > > > pthread_mutex_lock (&once_control->mutex); > > > - /* Here we must set a cancellation handler to unlock the mutex if > > > needed */ > > > - /* but a cancellation handler is not the right thing. We need this in > > > the thread > > > - *cleanup routine. Assumption: a thread can only be in one > > > pthread_once routine > > > - *at a time. Stote a mutex_t *in the pthread_structure. if that's non > > > null unlock > > > - *on pthread_exit (); > > > - */ > > > > Sorry, in a unified diff form this is unreadable. One needs to look at the > > entire function. A context diff would have been better. So: > > > > int > > pthread::once (pthread_once_t *once_control, void (*init_routine) (void)) > > { > > /* Sign bit of once_control->state is used as done flag */ > > if (once_control->state & INT_MIN) > > return 0; > > > > /* The type of &once_control->state is int *, which is compatible with > > LONG * (the type of the first argument of InterlockedIncrement()). */ > > InterlockedIncrement (&once_control->state); > > pthread_mutex_lock (&once_control->mutex); > > if (!(once_control->state & INT_MIN)) > > { > > init_routine (); > > once_control->state |= INT_MIN; > > } > > pthread_mutex_unlock (&once_control->mutex); > > if (InterlockedDecrement (&once_control->state) == INT_MIN) > > pthread_mutex_destroy (&once_control->mutex); > > return 0; > > }
With v3 patch: int pthread::once (pthread_once_t *once_control, void (*init_routine) (void)) { /* Sign bit of once_control->state is used as done flag */ if (once_control->state & INT_MIN) return 0; /* The type of &once_control->state is int *, which is compatible with LONG * (the type of the first argument of InterlockedIncrement()). */ InterlockedIncrement (&once_control->state); pthread_mutex_lock (&once_control->mutex); if (!(once_control->state & INT_MIN)) { init_routine (); InterlockedOr (&once_control->state, INT_MIN); } pthread_mutex_unlock (&once_control->mutex); if (InterlockedDecrement (&once_control->state) == INT_MIN) pthread_mutex_destroy (&once_control->mutex); return 0; } -- Takashi Yano <takashi.y...@nifty.ne.jp>