diff options
author | rpj <rpj> | 2000-07-25 16:14:23 +0000 |
---|---|---|
committer | rpj <rpj> | 2000-07-25 16:14:23 +0000 |
commit | e2fd6e2de322cc12d9153da548ab76379049c11c (patch) | |
tree | 0e055e3496bbe45a4003d3e140e09a763d116fda /create.c | |
parent | b035ed05977fdef5ced4691028284b7f0ebaba19 (diff) |
2000-07-25 Ross Johnson <rpj@special.ise.canberra.edu.au>
* sched.c (sched_get_priority_max): Handle different WinCE and
Win32 priority values together.
(sched_get_priority_min): Ditto.
- Tristan Savatier <tristan@mpegtv.com>
* create.c (pthread_create): Force new threads to wait until
pthread_create has the new thread's handle; we also retain
a local copy of the handle for internal use until
pthread_create returns.
* private.c (_pthread_threadStart): Initialise ei[].
(_pthread_threadStart): When beginthread is used to start the
thread, force waiting until the creator thread had the
thread handle.
* cancel.c (_pthread_cancel_thread): Include context switch
code for defined(_X86_) environments in addition to _M_IX86.
* rwlock.c (pthread_rwlock_destroy): Assignment changed
to avoid compiler warning.
* private.c (_pthread_get_exception_services_code): Cast
NULL return value to avoid compiler warning.
* cleanup.c (pthread_pop_cleanup): Initialise "cleanup" variable
to avoid compiler warnings.
* misc.c (_pthread_new): Change "new" variable to "t" to avoid
confusion with the C++ keyword of the same name.
* condvar.c (cond_wait_cleanup): Initialise lastWaiter variable.
(cond_timedwait): Remove unused local variables. to avoid
compiler warnings.
* dll.c (dllMain): Remove 2000-07-21 change - problem
appears to be in pthread_create().
2000-07-22 Ross Johnson <rpj@special.ise.canberra.edu.au>
* tsd.c (pthread_key_create): If a destructor was given
and the pthread_mutex_init failed, then would try to
reference a NULL pointer (*key); eliminate this section of
code by using a dynamically initialised mutex
(PTHREAD_MUTEX_INITIALIZER).
* tsd.c (pthread_setspecific): Return an error if
unable to set the value; simplify cryptic conditional.
* tsd.c (pthread_key_delete): Locking threadsLock relied
on mutex_lock returning an error if the key has no destructor.
ThreadsLock is only initialised if the key has a destructor.
Making this mutex a static could reduce the number of mutexes
used by an application since it is actually created only at
first use and it's often destroyed soon after.
2000-07-22 Ross Johnson <rpj@special.ise.canberra.edu.au>
* FAQ: Added Q5 and Q6.
tests/ChangeLog:
2000-07-25 Ross Johnson <rpj@special.ise.canberra.edu.au>
* runtest.bat: modified to work under W98.
* runall.bat: Add new tests; modified to work under W98.
It was ok under NT.
* Makefile: Add new tests.
* exception1.c: New; Test passing exceptions back to the
application and retaining library internal exceptions.
* join0.c: New; Test a single join.
Diffstat (limited to 'create.c')
-rw-r--r-- | create.c | 44 |
1 files changed, 33 insertions, 11 deletions
@@ -68,6 +68,7 @@ pthread_create (pthread_t * tid, */ { pthread_t thread; + HANDLE threadH = 0; int result = EAGAIN; int run = TRUE; ThreadParms *parms = NULL; @@ -90,8 +91,7 @@ pthread_create (pthread_t * tid, goto FAIL0; } - if ((parms = (ThreadParms *) malloc (sizeof (*parms))) == - NULL) + if ((parms = (ThreadParms *) malloc (sizeof (*parms))) == NULL) { goto FAIL0; } @@ -117,7 +117,7 @@ pthread_create (pthread_t * tid, /* * Default stackSize */ - stackSize = 0; + stackSize = PTHREAD_STACK_MIN; } thread->state = run @@ -126,20 +126,40 @@ pthread_create (pthread_t * tid, thread->keys = NULL; + /* + * Threads must be started in suspended mode and resumed if necessary + * after _beginthreadex returns us the handle. Otherwise we set up a + * race condition between the creating and the created threads. + * Note that we also retain a local copy of the handle for use + * by us in case thread->threadH gets NULLed later but before we've + * finished with it here. + */ + #if ! defined (__MINGW32__) || defined (__MSVCRT__) - thread->threadH = (HANDLE) + thread->threadH = threadH = (HANDLE) _beginthreadex ( (void *) NULL, /* No security info */ (unsigned) stackSize, /* default stack size */ (unsigned (PT_STDCALL *) (void *)) _pthread_threadStart, parms, - (unsigned) run ? 0 : CREATE_SUSPENDED, + (unsigned) CREATE_SUSPENDED, (unsigned *) &(thread->thread)); + if (threadH != 0 && run) + { + ResumeThread(threadH); + } + #else /* __MINGW32__ && ! __MSVCRT__ */ - thread->threadH = (HANDLE) + /* + * This lock will force pthread_threadStart() to wait until we have + * the thread handle. + */ + (void) pthread_mutex_lock(&thread->cancelLock); + + thread->threadH = threadH = (HANDLE) _beginthread ( (void (*) (void *)) _pthread_threadStart, (unsigned) stackSize, /* default stack size */ @@ -148,23 +168,25 @@ pthread_create (pthread_t * tid, /* * Make the return code match _beginthreadex's. */ - if (thread->threadH == (HANDLE)-1L) + if (threadH == (HANDLE) -1L) { - thread->threadH = 0; + thread->threadH = threadH = 0; } else if (! run) { - /* + /* * beginthread does not allow for create flags, so we do it now. * Note that beginthread itself creates the thread in SUSPENDED * mode, and then calls ResumeThread to start it. */ - SuspendThread (thread->threadH); + SuspendThread (threadH); } + (void) pthread_mutex_unlock(&thread->cancelLock); + #endif /* __MINGW32__ && ! __MSVCRT__ */ - result = (thread->threadH != 0) ? 0 : EAGAIN; + result = (threadH != 0) ? 0 : EAGAIN; /* * Fall Through Intentionally |