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>

Reply via email to