summaryrefslogtreecommitdiff
path: root/create.c
diff options
context:
space:
mode:
authorrpj <rpj>2000-07-25 16:14:23 +0000
committerrpj <rpj>2000-07-25 16:14:23 +0000
commite2fd6e2de322cc12d9153da548ab76379049c11c (patch)
tree0e055e3496bbe45a4003d3e140e09a763d116fda /create.c
parentb035ed05977fdef5ced4691028284b7f0ebaba19 (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.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/create.c b/create.c
index ac1384f..48d0984 100644
--- a/create.c
+++ b/create.c
@@ -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