summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog17
-rw-r--r--cancel.c38
-rw-r--r--create.c12
-rw-r--r--exit.c1
-rw-r--r--implement.h9
-rw-r--r--pthread.h7
6 files changed, 74 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index e13ca49..47e8acf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+Fri Jul 24 21:13:55 1998 Ross Johnson <rpj@ixobrychus.canberra.edu.au>
+
+ * cancel.c (pthread_cancel): Implement.
+ (pthread_testcancel): Implement.
+
+ * exit.c (pthread_exit): Add comment explaining the longjmp().
+
+ * implement.h (_pthread_threads_thread_t): New member cancelthread.
+ (_PTHREAD_YES): Define.
+ (_PTHREAD_NO): Define.
+ (RND_SIZEOF): Remove.
+
+ * create.c (pthread_create): Rename cancelability to cancelstate.
+
+ * pthread.h (pthread_attr_t): Rename cancelability to cancelstate.
+ (PTHREAD_CANCELED): Define.
+
1998-07-24 Ben Elliston <bje@cygnus.com>
* pthread.h (SIG_BLOCK): Define if not already defined.
diff --git a/cancel.c b/cancel.c
index 72c41ad..e9e33f1 100644
--- a/cancel.c
+++ b/cancel.c
@@ -47,3 +47,41 @@ pthread_setcanceltype(int type, int *oldtype)
this->canceltype = type;
return 0;
}
+
+int
+pthread_cancel(pthread_t thread)
+{
+ _pthread_threads_thread_t * this;
+
+ this = _PTHREAD_THIS;
+
+ if (this == NULL)
+ {
+ return ESRCH;
+ }
+
+ this->cancelthread = _PTHREAD_YES;
+
+ return 0;
+}
+
+void
+pthread_testcancel(void)
+{
+ _pthread_threads_thread_t * this;
+
+ this = _PTHREAD_THIS;
+
+ if (this == NULL ||
+ this->attr.cancelstate == PTHREAD_CANCEL_DISABLE)
+ {
+ return;
+ }
+
+ if (this->cancelthread == _PTHREAD_YES)
+ {
+ pthread_exit(PTHREAD_CANCELED);
+
+ /* Never reached. */
+ }
+}
diff --git a/create.c b/create.c
index 74d207d..ce12849 100644
--- a/create.c
+++ b/create.c
@@ -19,13 +19,15 @@ _pthread_start_call(void * thisarg)
/* We're now in a running thread. Any local variables here are on
this threads private stack so we're safe to leave data in them
until we leave. */
- _pthread_threads_thread__t * this = thisarg;
+ _pthread_threads_thread__t * this;
_pthread_call_t * call;
unsigned (*func)(void *);
void * arg;
unsigned ret;
int from;
+ this = (_pthread_threads_thread__t *) thisarg;
+
if (this->detached == PTHREAD_CREATE_DETACHED)
{
(void) CloseHandle(this->thread);
@@ -39,13 +41,15 @@ _pthread_start_call(void * thisarg)
if (from == 0)
{
+ /* Normal return from setjmp(). */
ret = (*func)(arg);
_pthread_vacuum();
}
else
{
- /* func() called pthread_exit() which called longjmp(). */
+ /* longjmp() teleported us here.
+ func() called pthread_exit() which called longjmp(). */
_pthread_vacuum();
/* Never returns. */
@@ -82,7 +86,7 @@ pthread_create(pthread_t *thread,
attr_copy->stacksize = PTHREAD_STACK_MIN;
}
- attr_copy->cancelability = attr->cancelability;
+ attr_copy->cancelstate = attr->cancelstate;
attr_copy->canceltype = attr->canceltype;
attr_copy->detached = attr->detached;
attr_copy->priority = attr->priority;
@@ -119,7 +123,7 @@ pthread_create(pthread_t *thread,
}
else
{
- /* Undo everything. */
+ /* Remove the failed thread entry. */
_pthread_delete_thread_entry(this);
}
diff --git a/exit.c b/exit.c
index 1e07ccd..a32e0ca 100644
--- a/exit.c
+++ b/exit.c
@@ -48,5 +48,6 @@ pthread_exit(void * value)
/* FIXME: More to do here. IE, if pthread_detach() was called
and value != NULL, do we free(value)? */
+ /* Teleport back to _pthread_start_call() to cleanup and exit. */
longjmp(this->call.env, 1);
}
diff --git a/implement.h b/implement.h
index 4a9a5ad..033e0e8 100644
--- a/implement.h
+++ b/implement.h
@@ -9,6 +9,9 @@
#define _PTHREAD_HASH_INDEX(x) (((ULONG) x) % PTHREAD_THREADS_MAX)
+#define _PTHREAD_YES 1
+#define _PTHREAD_NO 0
+
/* Handler execution flags. */
#define _PTHREAD_HANDLER_NOEXECUTE 0
#define _PTHREAD_HANDLER_EXECUTE 1
@@ -19,11 +22,6 @@ enum { _PTHREAD_HANDLER_POP_LIFO, _PTHREAD_HANDLER_POP_FIFO };
/* Special value to mark attribute objects as valid. */
#define _PTHREAD_ATTR_INVALID 0xC0FFEE
-/* Round a sizeof(type) up to a multiple of sizeof(DWORD).
- This is all compile time arithmetic.
- */
-#define RND_SIZEOF(T) (((sizeof(T) / sizeof(DWORD)) + 1) * sizeof(DWORD))
-
/* General description of a handler function on a stack. */
typedef struct _pthread_handler_node _pthread_handler_node_t;
@@ -52,6 +50,7 @@ struct _pthread_threads_thread {
pthread_t thread;
pthread_attr_t attr;
_pthread_call_t call;
+ int cancelthread;
void ** joinvalueptr;
_pthread_handler_node_t * cleanupstack;
_pthread_handler_node_t * destructorstack;
diff --git a/pthread.h b/pthread.h
index 70ece60..de84697 100644
--- a/pthread.h
+++ b/pthread.h
@@ -70,6 +70,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define PTHREAD_CANCEL_ASYNCHRONOUS 0
#define PTHREAD_CANCEL_DEFERRED 1
+/* Cancelation return value.
+ This value must be neither NULL nor the value of any
+ pointer to an object in memory. */
+#define PTHREAD_CANCELED ((void *) 1)
+
typedef HANDLE pthread_t;
typedef CRITICAL_SECTION pthread_mutex_t;
typedef DWORD pthread_key_t;
@@ -83,7 +88,7 @@ typedef struct {
size_t stacksize; /* PTHREAD_STACK_MIN */
#endif
- int cancelability; /* PTHREAD_CANCEL_DISABLE
+ int cancelstate; /* PTHREAD_CANCEL_DISABLE
PTHREAD_CANCEL_ENABLE */
int detached; /* PTHREAD_CREATE_DETACHED