summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog22
-rw-r--r--cancel.c35
-rw-r--r--create.c15
-rw-r--r--implement.h7
-rw-r--r--private.c71
-rw-r--r--pthread.h6
-rw-r--r--sync.c56
7 files changed, 122 insertions, 90 deletions
diff --git a/ChangeLog b/ChangeLog
index 18ed5cd..ea0fdcc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+Sun Jul 26 00:09:59 1998 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * private.c (_pthread_delete_thread_entry): Mutex locks removed.
+ Mutexes must be applied at the caller level.
+ (_pthread_new_thread_entry): Ditto.
+ (_pthread_new_thread_entry): Init cancelstate, canceltype, and
+ cancel_pending to default values.
+ (_pthread_new_thread_entry): Rename "this" to "new".
+ (_pthread_find_thread_entry): Rename "this" to "entry".
+ (_pthread_delete_thread_entry): Rename "thread_entry" to "entry".
+
+ * create.c (_pthread_start_call): Mutexes changed to
+ _pthread_count_mutex. All access to the threads table entries is
+ under the one mutex. Otherwise chaos reigns.
+
+Sat Jul 25 23:16:51 1998 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * implement.h (_pthread_threads_thread): Move cancelstate and
+ canceltype members out of pthread_attr_t into here.
+
+ * fork.c (fork): Add comment.
+
1998-07-25 Ben Elliston <bje@cygnus.com>
* fork.c (fork): Autoconfiscate.
diff --git a/cancel.c b/cancel.c
index e9e33f1..1b48b28 100644
--- a/cancel.c
+++ b/cancel.c
@@ -6,6 +6,7 @@
*/
#include "pthread.h"
+#include "implement.h"
int
pthread_setcancelstate(int state,
@@ -14,53 +15,53 @@ pthread_setcancelstate(int state,
_pthread_threads_thread_t * this = *_PTHREAD_THIS;
/* Validate the new cancellation state. */
- if (state != PTHREAD_CANCEL_ENABLE || state != PTHREAD_CANCEL_DISABLE)
+ if (state != PTHREAD_CANCEL_ENABLE
+ || state != PTHREAD_CANCEL_DISABLE)
{
return EINVAL;
}
if (oldstate != NULL)
{
- *oldstate = this->cancelability;
+ *oldstate = this->cancelstate;
}
- this->cancelability = state;
+ this->cancelstate = state;
return 0;
}
int
pthread_setcanceltype(int type, int *oldtype)
{
- _pthread_threads_thread_t * this = *_PTHREAD_THIS;
+ _pthread_threads_thread_t * us = _PTHREAD_THIS;
/* Validate the new cancellation type. */
- if (type != PTHREAD_CANCEL_DEFERRED || type != PTHREAD_CANCEL_ASYNCHRONOUS)
+ if (type != PTHREAD_CANCEL_DEFERRED
+ || type != PTHREAD_CANCEL_ASYNCHRONOUS)
{
return EINVAL;
}
if (oldtype != NULL)
{
- *oldtype = this->canceltype;
+ *oldtype = us->canceltype;
}
- this->canceltype = type;
+ us->canceltype = type;
return 0;
}
int
pthread_cancel(pthread_t thread)
{
- _pthread_threads_thread_t * this;
-
- this = _PTHREAD_THIS;
+ _pthread_threads_thread_t * us = _PTHREAD_THIS;
- if (this == NULL)
+ if (us == NULL)
{
return ESRCH;
}
- this->cancelthread = _PTHREAD_YES;
+ us->cancel_pending = TRUE;
return 0;
}
@@ -68,17 +69,17 @@ pthread_cancel(pthread_t thread)
void
pthread_testcancel(void)
{
- _pthread_threads_thread_t * this;
+ _pthread_threads_thread_t * us;
- this = _PTHREAD_THIS;
+ us = _PTHREAD_THIS;
- if (this == NULL ||
- this->attr.cancelstate == PTHREAD_CANCEL_DISABLE)
+ if (us == NULL
+ || us->cancelstate == PTHREAD_CANCEL_DISABLE)
{
return;
}
- if (this->cancelthread == _PTHREAD_YES)
+ if (us->cancel_pending == TRUE)
{
pthread_exit(PTHREAD_CANCELED);
diff --git a/create.c b/create.c
index 2a94baf..8cc5a57 100644
--- a/create.c
+++ b/create.c
@@ -20,7 +20,6 @@ _pthread_start_call(void * us_arg)
this threads private stack so we're safe to leave data in them
until we leave. */
_pthread_threads_thread__t * us;
- pthread_mutex_t * us_thread_mutex;
_pthread_call_t * call;
unsigned (*func)(void *);
void * arg;
@@ -39,8 +38,6 @@ _pthread_start_call(void * us_arg)
func = us->call.routine;
arg = us->call.arg;
- us_thread_mutex = _PTHREAD_THREAD_MUTEX(us);
-
/* FIXME: Should we be using sigsetjmp() here instead. */
from = setjmp(us->call.env);
@@ -55,7 +52,7 @@ _pthread_start_call(void * us_arg)
was called and there are no waiting joins. */
/* CRITICAL SECTION */
- pthread_mutex_lock(us_thread_mutex);
+ pthread_mutex_lock(&_pthread_count_mutex);
if (us->detach == TRUE
&& us->join_count == 0)
@@ -63,7 +60,7 @@ _pthread_start_call(void * us_arg)
_pthread_delete_thread_entry(us);
}
- pthread_mutex_lock(us_thread_mutex);
+ pthread_mutex_lock(&_pthread_count_mutex);
/* END CRITICAL SECTION */
}
else
@@ -76,7 +73,7 @@ _pthread_start_call(void * us_arg)
was called and there are no waiting joins. */
/* CRITICAL SECTION */
- pthread_mutex_lock(us_thread_mutex);
+ pthread_mutex_lock(&_pthread_count_mutex);
if (us->detach == TRUE
&& us->join_count == 0)
@@ -84,7 +81,7 @@ _pthread_start_call(void * us_arg)
_pthread_delete_thread_entry(us);
}
- pthread_mutex_lock(us_thread_mutex);
+ pthread_mutex_lock(&_pthread_count_mutex);
/* END CRITICAL SECTION */
ret = 0;
@@ -130,10 +127,10 @@ pthread_create(pthread_t *thread,
#if HAVE_SIGSET_T
memcpy(&(attr_copy->sigmask), &(attr->sigmask), sizeof(sigset_t));
#endif /* HAVE_SIGSET_T */
-
- this->detach = (attr->detachedstate == PTHREAD_CREATE_DETACHED);
}
+ this->detach = (attr->detachedstate == PTHREAD_CREATE_DETACHED);
+
/* Start running, not suspended. */
flags = 0;
diff --git a/implement.h b/implement.h
index 807bf0e..3216573 100644
--- a/implement.h
+++ b/implement.h
@@ -62,7 +62,12 @@ struct _pthread_threads_thread {
pthread_t thread;
pthread_attr_t attr;
_pthread_call_t call;
- int cancelthread;
+ int cancel_pending;
+ int cancelstate; /* PTHREAD_CANCEL_DISABLE
+ PTHREAD_CANCEL_ENABLE */
+
+ int canceltype; /* PTHREAD_CANCEL_ASYNCHRONOUS
+ PTHREAD_CANCEL_DEFERRED */
void ** joinvalueptr;
int join_count;
_pthread_handler_node_t * cleanupstack;
diff --git a/private.c b/private.c
index d77f0b2..cee84e9 100644
--- a/private.c
+++ b/private.c
@@ -6,8 +6,6 @@
* the implementation and may be used throughout it.
*/
-#include <windows.h>
-#include <process.h>
#include "pthread.h"
#include "implement.h"
@@ -27,51 +25,48 @@
int
_pthread_new_thread_entry(pthread_t thread, _pthread_threads_thread_t * entry)
{
- _pthread_threads_thread_t * this;
-
- /* CRITICAL SECTION */
- pthread_mutex_lock(&_pthread_count_mutex);
+ _pthread_threads_thread_t * new;
if (_pthread_threads_count >= PTHREAD_THREADS_MAX)
{
return EAGAIN;
}
- this = &_pthread_threads_table[_PTHREAD_HASH_INDEX(thread)];
+ new = &_pthread_threads_table[_PTHREAD_HASH_INDEX(thread)];
- while (this->thread != NULL)
+ while (new->thread != NULL)
{
- this++;
+ new++;
- if (this == &_pthread_threads_table[PTHREAD_THREADS_MAX])
+ if (new == &_pthread_threads_table[PTHREAD_THREADS_MAX])
{
/* Wrap to the top of the table. */
- this == _pthread_threads_table;
+ new == _pthread_threads_table;
}
}
- if (this->thread != NULL)
+ if (new->thread != NULL)
{
/* INTERNAL ERROR: There should be at least one slot left. */
return ESRCH;
}
else
{
- this->thread = thread;
- pthread_attr_init(&(this->attr));
- this->joinvalueptr = NULL;
- this->cleanupstack = NULL;
- this->destructorstack = NULL;
- this->forkpreparestack = NULL;
- this->forkparentstack = NULL;
- this->forkchildstack = NULL;
+ new->thread = thread;
+ pthread_attr_init(&(new->attr));
+ new->joinvalueptr = NULL;
+ new->cancelstate = PTHREAD_CANCEL_ENABLE;
+ new->canceltype = PTHREAD_CANCEL_DEFERRED;
+ new->cancel_pending = FALSE;
+ new->cleanupstack = NULL;
+ new->destructorstack = NULL;
+ new->forkpreparestack = NULL;
+ new->forkparentstack = NULL;
+ new->forkchildstack = NULL;
}
_pthread_threads_count++;
- entry = this;
-
- pthread_mutex_unlock(&_pthread_count_mutex);
- /* END CRITICAL SECTION */
+ entry = new;
return 0;
}
@@ -79,45 +74,42 @@ _pthread_new_thread_entry(pthread_t thread, _pthread_threads_thread_t * entry)
_pthread_threads_thread *
_pthread_find_thread_entry(pthread_t thread)
{
- _pthread_threads_thread_t * this;
+ _pthread_threads_thread_t * entry;
_pthread_threads_thread_t * start;
- start = this = &_pthread_threads_table[_PTHREAD_HASH_INDEX(thread)];
+ start = entry = &_pthread_threads_table[_PTHREAD_HASH_INDEX(thread)];
- while (this->thread != thread)
+ while (entry->thread != thread)
{
- this++;
+ entry++;
- if (this == &_pthread_threads_table[PTHREAD_THREADS_MAX])
+ if (entry == &_pthread_threads_table[PTHREAD_THREADS_MAX])
{
/* Wrap to top of table. */
- this = _pthread_threads_table;
+ entry = _pthread_threads_table;
}
}
- if (this->thread == NULL || this == start)
+ if (entry->thread == NULL || entry == start)
{
/* Failed to find the thread. */
return NULL;
}
- return this;
+ return entry;
}
void
-_pthread_delete_thread_entry(_pthread_threads_thread_t * thread_entry)
+_pthread_delete_thread_entry(_pthread_threads_thread_t * entry)
{
/* We don't check that the thread has been properly cleaned up, so
it had better be done already. */
- /* CRITICAL SECTION */
- pthread_mutex_lock(&_pthread_count_mutex);
-
/* Remove the thread entry if necessary. */
- if (thread_entry->thread != NULL)
+ if (entry->thread != NULL)
{
- thread_entry->thread = NULL;
+ entry->thread = NULL;
if (_pthread_threads_count > 0)
{
@@ -132,7 +124,4 @@ _pthread_delete_thread_entry(_pthread_threads_thread_t * thread_entry)
{
/* FIXME: INTERNAL ERROR: This should not happen. */
}
-
- pthread_mutex_unlock(&_pthread_count_mutex);
- /* END CRITICAL SECTION */
}
diff --git a/pthread.h b/pthread.h
index 0c0036b..cce502a 100644
--- a/pthread.h
+++ b/pthread.h
@@ -88,15 +88,9 @@ typedef struct {
size_t stacksize; /* PTHREAD_STACK_MIN */
#endif
- int cancelstate; /* PTHREAD_CANCEL_DISABLE
- PTHREAD_CANCEL_ENABLE */
-
int detachedstate; /* PTHREAD_CREATE_DETACHED
PTHREAD_CREATE_JOINABLE */
- int canceltype; /* PTHREAD_CANCEL_ASYNCHRONOUS
- PTHREAD_CANCEL_DEFERRED */
-
#ifdef HAVE_SIGSET_T
sigset_t sigmask;
#endif /* HAVE_SIGSET_T */
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;
}