This is the mail archive of the mailing list for the Cygwin project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: contribution soapbox(was Re: G++ guru's please comment - Re: FW: pthread_create problem in Cygwin 1.1.8-2])

----- Original Message -----
From: "RenÚ M°ller Fonseca" <>
To: "Robert Collins" <>
Cc: <>
Sent: Tuesday, April 10, 2001 7:05 PM
Subject: Re: contribution soapbox(was Re: G++ guru's please comment -
Re: FW: pthread_create problem in Cygwin 1.1.8-2])

> Hi again,
> I wasn't aware of the Interlocked functions.
> I just examined the documentation for InterlockedIncrement and it
> that the variables must be aligned on a 32-bit boundary.
> On Solaris the error code EINVAL is returned if either once_control or
> init_routine is NULL. You should consider returning EINVAL (or other
> appropriate error code) if once_contol isn't 32 bit aligned.
> >>>>
> int __pthread_once (pthread_once_t * once_control, void
> (void))
>  {
>    if ((once_control & 0x03) != 0) { // must be checked before use of
> Interlocked...
>      return EINVAL;
>    }
>    if (InterlockedDecrement(once_control)!=0)
>      {
>        InterlockIncrement(once_control);
>        return 0;
>      }
>     init_routine();
>    /* cancel test will go here when canceability states are
>  */
>   /* if (init_routine was canceled)
>       InterlockIncrement(once_control); */
>   return 0;
> }
> <<<<
> I do not understand why other threads should not block until
> init_routine has been completed. The few uses of pthread_once that I
> have seen allocate resources and initializes variables that are
> to be correct after pthread_once has completed, for the following code
> the work correctly. If a thread could return from pthread_once without
> an error and before init_routine was invoked then the code wouldn't
> work. I can't direct you to the code I'm refering to 'cause I can't
> remember where I seen it, sorry.

What if the init_routine deadlocks? If the other threads are blocked the
program cannot cancel the init routine. Blocking each thread that
chooses to call pthread_once makes more sense to me.

I'm happy to make the function behave compatibly with (insert open
source O/S name here). If you write a small test program, and run on
linux/*BSD and report back with the results and the test program, I'll
adjust the code. Until then, my call is "other threads don't block".
And no, I can't just look at the BSD/Linux source code and decide -
cygwin itself isn't open source compatible because of the need to
release a commercial variant. Thus the need for test cases.

> I did a man pthread_once on a machine running Irix 6.5. and came up
> this:
> >>>>>
>      #include <pthread.h>
>      int pthread_once(pthread_once_t *once, void (*init)(void));
>      The pthread_once() function ensures that the function init is
> called
>      exactly once for all callers using the once initialization
> variable.
>      This variable is initialized with the constant PTHREAD_ONCE_INIT.
> While
>      init is being executed all callers of pthread_once() will wait.

The doc's I'm coding off
don't mention the wait. As I've indicated I'm happy to change what's
written to be more compatible. I would appreciate an actual test result
and test program. Also for efficiency I think only calls to pthread_once
with the same once parameter should block. Calls with a different once
parameter should proceed uninhibited. (If you do a test prog, that would
be a good test - have two separate once variables and see whether both
callers hit the init routine at the same time).

>      If a thread is cancelled while executing the init function [see
>      pthread_setcancelstate()], then pthread_once() will permit
> thread
>      (possibly waiting) to make the call.
> <<<<<
> I have also found this:
> The man page for pthread_once for Solaris 8 doesn't mention anything
> about the blocking behaviour.
> RenÚ

In fact, looking at it, I'll change this to block all threads that call
pthread_once with the same once variable. However I would really
appreciate a test case with multiple once variables to see if a global
block is needed, or a block per once variable.


Want to unsubscribe from this list?
Check out:

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]