From eafdb5db2871e893574fd0da01554d1a50b7471f Mon Sep 17 00:00:00 2001
From: rpj <rpj>
Date: Fri, 24 Jul 1998 12:21:27 +0000
Subject: 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.
---
 ChangeLog   | 17 +++++++++++++++++
 cancel.c    | 38 ++++++++++++++++++++++++++++++++++++++
 create.c    | 12 ++++++++----
 exit.c      |  1 +
 implement.h |  9 ++++-----
 pthread.h   |  7 ++++++-
 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
-- 
cgit v1.2.3