pthread_testcancel() causes SEGV

Robert Collins rbcollins@cygwin.com
Tue Sep 10 08:21:00 GMT 2002


On Thu, 2002-08-08 at 04:54, Jason Tishler wrote:
> Thomas,
> 
> On Wed, Aug 07, 2002 at 09:34:14AM +0200, Thomas Pfaff wrote:
> > Thanks for tracking it down.
> 
> No problem.  Thanks for the quick turn around on the patch.  I tested it
> and can confirm that it fixes the ipc-daemon service startup problem.

Jason, 
sorry for the *cough* long delay. 

the attached patch is the 'right way' to deal with this issue IMO. It
also gives us full pthread* support for threads created using the win32
CreateThread call (although I won't officially support that at this
point :}).

Generally speaking, when you find yourself writing the same bit of code
twice, the design is wrong. Anyway, enough said:

ChangeLog
2002-09-11  Robert Collins  <rbtcollins@hotmail.com>

	* init.cc (dll_entry): On thread detach, if the thread hasn't
	exit()ed, do so.
	* thread.cc (pthread::self): Instantiate a new pthread object 
	when called and none exists.
	(pthread::precreate): Factor out common code.
	(pthread::postcreate): Ditto.
	(pthread::create): Ditto.
	(pthread::exit): Remove the TLS value when we exit to prevent
	double exits.
	* thread.h (pthread): Declare pre- and post-create.

Rob
-------------- next part --------------
? cvs.exe.stackdump
? cygwin_daemon.patch
? localdiff
? pthread_cancel.patch
? pthread_fix.patch
? pthread_self_fix.patch
? t
Index: init.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/init.cc,v
retrieving revision 1.14
diff -u -p -r1.14 init.cc
--- init.cc	10 Oct 2001 02:32:12 -0000	1.14
+++ init.cc	10 Sep 2002 15:15:50 -0000
@@ -35,6 +35,13 @@ WINAPI dll_entry (HANDLE h, DWORD reason
     case DLL_PROCESS_DETACH:
       break;
     case DLL_THREAD_DETACH:
+      pthread *thisthread = (pthread *) TlsGetValue (
+			user_data->threadinterface->thread_self_dwTlsIndex);
+      if (thisthread) {
+	  /* Some non-pthread call created this thread, 
+	   * but we need to clean it up */
+	  thisthread->exit(0);
+      }
 #if 0 // FIXME: REINSTATE SOON
       waitq *w;
       if ((w = waitq_storage.get ()) != NULL)
Index: thread.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/thread.cc,v
retrieving revision 1.76
diff -u -p -r1.76 thread.cc
--- thread.cc	4 Jul 2002 14:17:29 -0000	1.76
+++ thread.cc	10 Sep 2002 15:15:50 -0000
@@ -350,7 +350,16 @@ MTinterface::fixup_after_fork (void)
 pthread *
 pthread::self ()
 {
-  return (pthread *) TlsGetValue (MT_INTERFACE->thread_self_dwTlsIndex);
+  pthread *temp = (pthread *) TlsGetValue (MT_INTERFACE->thread_self_dwTlsIndex);
+  if (temp)
+      return temp;
+  temp = new pthread ();
+  temp->precreate (NULL);
+  if (!temp->magic)
+    /* Something seriously wrong */
+    return NULL; 
+  temp->postcreate ();
+  return temp;
 }
 
 /* member methods */
@@ -370,8 +379,7 @@ pthread::~pthread ()
 
 
 void
-pthread::create (void *(*func) (void *), pthread_attr *newattr,
-		 void *threadarg)
+pthread::precreate (pthread_attr *newattr)
 {
   pthread_mutex *verifyable_mutex_obj = &mutex;
 
@@ -386,8 +394,6 @@ pthread::create (void *(*func) (void *),
       attr.inheritsched = newattr->inheritsched;
       attr.stacksize = newattr->stacksize;
     }
-  function = func;
-  arg = threadarg;
 
   if (verifyable_object_isvalid (&verifyable_mutex_obj, PTHREAD_MUTEX_MAGIC) != VALID_OBJECT)
     {
@@ -405,6 +411,17 @@ pthread::create (void *(*func) (void *),
       magic = 0;
       return;
     }
+}
+
+void
+pthread::create (void *(*func) (void *), pthread_attr *newattr,
+		 void *threadarg)
+{ 
+  precreate (newattr);
+  if (!magic)
+      return;
+   function = func;
+   arg = threadarg;
 
   win32_obj_id = ::CreateThread (&sec_none_nih, attr.stacksize,
 				(LPTHREAD_START_ROUTINE) thread_init_wrapper,
@@ -415,17 +432,22 @@ pthread::create (void *(*func) (void *),
       thread_printf ("CreateThread failed: this %p LastError %E", this);
       magic = 0;
     }
-  else
-    {
-      InterlockedIncrement (&MT_INTERFACE->threadcount);
-      /*FIXME: set the priority appropriately for system contention scope */
-      if (attr.inheritsched == PTHREAD_EXPLICIT_SCHED)
-	{
-	  /*FIXME: set the scheduling settings for the new thread */
-	  /*sched_thread_setparam (win32_obj_id, attr.schedparam); */
-	}
+  else {
+      postcreate ();
       ResumeThread (win32_obj_id);
-    }
+  }
+}
+
+void
+pthread::postcreate ()
+{
+    InterlockedIncrement (&MT_INTERFACE->threadcount);
+    /*FIXME: set the priority appropriately for system contention scope */
+    if (attr.inheritsched == PTHREAD_EXPLICIT_SCHED)
+      {
+	/*FIXME: set the scheduling settings for the new thread */
+	/*sched_thread_setparam (win32_obj_id, attr.schedparam); */
+      }
 }
 
 void
@@ -447,6 +469,9 @@ pthread::exit (void *value_ptr)
       return_ptr = value_ptr;
       mutex.UnLock ();
     }
+
+  /* Prevent DLL_THREAD_DETACH Attempting to clean us up */
+  TlsSetValue (MT_INTERFACE->thread_self_dwTlsIndex, 0);
 
   if (InterlockedDecrement (&MT_INTERFACE->threadcount) == 0)
     ::exit (0);
Index: thread.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/thread.h,v
retrieving revision 1.40
diff -u -p -r1.40 thread.h
--- thread.h	4 Jul 2002 14:17:29 -0000	1.40
+++ thread.h	10 Sep 2002 15:15:50 -0000
@@ -284,6 +284,8 @@ public:
   sigset_t *sigmask;
   LONG *sigtodo;
   void create (void *(*)(void *), pthread_attr *, void *);
+  void precreate (pthread_attr *);
+  void postcreate ();
 
     pthread ();
    ~pthread ();
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
URL: <http://cygwin.com/pipermail/cygwin-patches/attachments/20020910/2f42ee3a/attachment.sig>


More information about the Cygwin-patches mailing list