summaryrefslogtreecommitdiff
path: root/sync.c
diff options
context:
space:
mode:
Diffstat (limited to 'sync.c')
-rw-r--r--sync.c56
1 files changed, 40 insertions, 16 deletions
diff --git a/sync.c b/sync.c
index 84d9bd9..e9b5bc2 100644
--- a/sync.c
+++ b/sync.c
@@ -76,21 +76,25 @@ pthread_join(pthread_t thread, void ** valueptr)
target_thread_mutex = _PTHREAD_THREAD_MUTEX(target);
/* CRITICAL SECTION */
- pthread_mutex_lock(target_thread_mutex);
+ pthread_mutex_lock(&_pthread_count_mutex);
/* If the thread is in DETACHED state, then join will return
immediately. */
- if (target->detach == TRUE)
+ if (pthread_attr_getdetachedstate(&(target->attr), &detachstate) != 0
+ || detachstate == PTHREAD_CREATE_DETACHED)
{
return EINVAL;
}
target->join_count++;
- pthread_mutex_lock(target_thread_mutex);
+ pthread_mutex_lock(&_pthread_count_mutex);
/* END CRITICAL SECTION */
+ /* CANCELATION POINT */
+ pthread_testcancel();
+
/* Wait on the kernel thread object. */
switch (WaitForSingleObject(thread, INFINITE))
{
@@ -152,26 +156,46 @@ pthread_join(pthread_t thread, void ** valueptr)
int
pthread_detach(pthread_t thread)
{
- _pthread_threads_thread_t * this;
+ _pthread_threads_thread_t * target;
int detachstate;
+ int ret;
+ pthread_mutex_t * target_thread_mutex;
- this = _pthread_find_thread_entry(thread);
+ /* CRITICAL SECTION */
+ pthread_mutex_lock(&_pthread_count_mutex);
- if (this == NULL)
+ target = _pthread_find_thread_entry(thread);
+
+ if (target == NULL)
{
- return ESRCH;
+ ret = ESRCH;
}
-
- /* Check that we can detach this thread. */
- if (pthread_attr_getdetachedstate(&(this->attr), &detachstate) != 0
- || detachstate == PTHREAD_CREATE_DETACHED)
+ else
{
- return EINVAL;
+
+ target_thread_mutex = _PTHREAD_THREAD_MUTEX(target);
+
+ /* Check that we can detach this thread. */
+ if (pthread_attr_getdetachedstate(&(target->attr), &detachstate) != 0
+ || detachstate == PTHREAD_CREATE_DETACHED)
+ {
+ ret = EINVAL;
+ }
+ else
+ {
+
+ /* This is all we do here - the rest is done either when the
+ thread exits or when pthread_join() exits. Once this is
+ set it will never be unset. */
+ pthread_attr_setdetachedstate(&(this->attr),
+ PTHREAD_CREATE_DETACHED);
+
+ ret = 0;
+ }
}
- /* This is all we do here - the rest is done either when the thread
- exits or when pthread_join() exits. */
- this->detach = TRUE;
+ pthread_mutex_unlock(&_pthread_count_mutex);
+ /* END CRITICAL SECTION */
- return 0;
+ return ret;
}