This is the mail archive of the pthreads-win32@sourceware.cygnus.com mailing list for the pthreas-win32 project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

RE: gcc mingw/crtdll patch


With regards to the return code not working...
In my original contributed work, the pthread_t structure contained
an unused attribute, "exitStatus" that can be used precisely for
the purpose of implementing the return code.

I didn't bother to use it since _endthreadex and GetExitCodeThread
did the trick just fine for WIN32.

However, if you need to use an alternative method, you simply can
do the following:

1) pthread_exit - stuff the result in t->exitStatus.
2) In _pthread_threadStart (?) if the user's thread routine actually
   returned, then stuff the return value in t->exitStatus.
3) In pthread_join, if the thread had terminated, simply extract
   the exit status from the instance of the thread structure.

If, however, you cannot use _endthreadex, the way to implement pthread_exit
is to throw the result as an exception back to an exception handler
in _pthread_threadStart and then stuff the result into the pthread_t there.
The trick, however, is trying to satisfy both C and C++ for throwing the
exception.
All the documentation I have read on C++ and pthreads is to never call
pthread_exit
from anywhere else but your thread main-line so that you do not circumvent
stack unwinding.

Just my 2 cents...

Sorry if I seem ignorant to what you are trying to do...

John.

-----Original Message-----
From: Mumit Khan [mailto:khan@xraylith.wisc.EDU]
Sent: Tuesday, August 17, 1999 9:27 PM
To: pthreads-win32@sourceware.cygnus.com
Subject: gcc mingw/crtdll patch


This patch adds support for CRTDLL, and most of the changes have to do
with the difference between MSVCRT begin/endthreadex and CRTDLL
begin/endthread pair. MSDN docs do describe the differences, as well
as http://support.microsoft.com/support/kb/articles/q132/0/78.asp

The only issue is the support of thread function return code that
won't work with CRTDLL, and that's why pthread_join will always
stuff 0 in the return area. I've noted that in the join1 test as
well. This can be "fixed", but that'll take some actual work as 
opposed to these trivial changes.

With join1 tweaked, all tests pass.

Patch requires my last one.

Tue Aug 17 20:17:58 CDT 1999  Mumit Khan  <khan@xraylith.wisc.edu>

	* create.c (pthread_create): Add CRTDLL suppport.
	* exit.c (pthread_exit): Likewise.
 	* private.c (_pthread_threadStart): Likewise.
	(_pthread_threadDestroy): Likewise.
	* sync.c (pthread_join): Likewise.
	* tests/join1.c (main): Warn about partial support for CRTDLL.

Index: create.c
===================================================================
RCS file: /homes/khan/src/CVSROOT/pthreads/create.c,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 create.c
--- create.c	1999/08/17 00:50:05	1.1.1.1
+++ create.c	1999/08/18 01:09:41
@@ -125,6 +125,8 @@ pthread_create (pthread_t * tid,
     : PThreadStateSuspended;
 
   thread->keys = NULL;
+#if ! defined (__MINGW32__) || defined (__MSVCRT__)
+
   thread->threadH = (HANDLE)
     _beginthreadex (
 		     (void *) NULL,	/* No security info             */
@@ -133,6 +135,27 @@ pthread_create (pthread_t * tid,
 		     parms,
 		     (unsigned) run ? 0 : CREATE_SUSPENDED,
 		     (unsigned *) &(thread->thread));
+
+#else /* __MINGW32__ && ! __MSVCRT__ */
+
+  thread->threadH = (HANDLE)
+    _beginthread (
+		   (void (*) (void *)) _pthread_threadStart,
+		   (unsigned) stackSize,	/* default stack size   */
+		   parms);
+
+  /* Make the return code to match _beginthreadex's.  */
+  if (thread->threadH == (HANDLE)-1L)
+    thread->threadH = NULL;
+  else if (! run)
+    {
+      /* beginthread does not allow for create flags, so we do it now.
+         Note that beginthread itself creates the thread in SUSPENDED
+	 mode, and then calls ResumeThread to start it.  */
+      SuspendThread (thread->threadH);
+    }
+
+#endif /* __MINGW32__ && ! __MSVCRT__ */
 
   result = (thread->threadH != 0) ? 0 : EAGAIN;
 
Index: exit.c
===================================================================
RCS file: /homes/khan/src/CVSROOT/pthreads/exit.c,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 exit.c
--- exit.c	1999/08/17 00:50:05	1.1.1.1
+++ exit.c	1999/08/18 01:09:41
@@ -66,7 +66,11 @@ pthread_exit (void *value_ptr)
     {
       _pthread_callUserDestroyRoutines(self);
 
+#if ! defined (__MINGW32__) || defined (__MSVCRT__)
       _endthreadex ((unsigned) value_ptr);
+#else
+      _endthread ();
+#endif
       
       /* Never reached */
     }
@@ -99,7 +103,11 @@ pthread_exit (void *value_ptr)
 
       _pthread_callUserDestroyRoutines(self);
 
+#if ! defined (__MINGW32__) || defined (__MSVCRT__)
       _endthreadex ((unsigned) value_ptr);
+#else
+      _endthread ();
+#endif
 
 #endif /* __cplusplus */
 
Index: implement.h
===================================================================
RCS file: /homes/khan/src/CVSROOT/pthreads/implement.h,v
retrieving revision 1.2
diff -u -3 -p -r1.2 implement.h
--- implement.h	1999/08/18 01:08:12	1.2
+++ implement.h	1999/08/18 01:10:20
@@ -321,7 +321,12 @@ void _pthread_threadDestroy (pthread_t t
 
 void _pthread_cleanupStack (void);
 
-unsigned PT_STDCALL _pthread_threadStart (ThreadParms * threadParms);
+#if ! defined (__MINGW32__) || defined (__MSVCRT__)
+unsigned PT_STDCALL
+#else
+void
+#endif
+_pthread_threadStart (ThreadParms * threadParms);
 
 void _pthread_callUserDestroyRoutines (pthread_t thread);
 
Index: private.c
===================================================================
RCS file: /homes/khan/src/CVSROOT/pthreads/private.c,v
retrieving revision 1.2
diff -u -3 -p -r1.2 private.c
--- private.c	1999/08/18 01:08:12	1.2
+++ private.c	1999/08/18 01:12:23
@@ -159,7 +159,11 @@ ExceptionFilter (EXCEPTION_POINTERS * ep
 
 #endif /* _MSC_VER */
 
+#if ! defined (__MINGW32__) || defined (__MSVCRT__)
 unsigned PT_STDCALL
+#else
+void
+#endif
 _pthread_threadStart (ThreadParms * threadParms)
 {
   pthread_t self;
@@ -178,6 +182,11 @@ _pthread_threadStart (ThreadParms * thre
   start = threadParms->start;
   arg = threadParms->arg;
 
+#if defined (__MINGW32__) && ! defined (__MSVCRT__)
+  /* beginthread does not return the thread id, and so we do it here. */
+  self->thread = GetCurrentThreadId ();
+#endif
+
   free (threadParms);
 
   pthread_setspecific (_pthread_selfThreadKey, self);
@@ -270,12 +279,18 @@ _pthread_threadStart (ThreadParms * thre
 
   _pthread_callUserDestroyRoutines(self);
 
+#if ! defined (__MINGW32__) || defined (__MSVCRT__)
   _endthreadex ((unsigned) status);
+#else
+  _endthread ();
+#endif
 
   /*
    * Never reached.
    */
+#if ! defined (__MINGW32__) || defined (__MSVCRT__)
   return (unsigned) status;
+#endif
 
 }				/* _pthread_threadStart */
 
@@ -291,10 +306,13 @@ _pthread_threadDestroy (pthread_t thread
 	  CloseHandle (thread->cancelEvent);
 	}
 
+#if ! defined (__MINGW32__) || defined (__MSVCRT__)
+      /* See documentation for endthread vs endthreadex. */
       if( thread->threadH != 0 )
 	{
 	  CloseHandle( thread->threadH );
 	}
+#endif
 
       free (thread);
     }
Index: sync.c
===================================================================
RCS file: /homes/khan/src/CVSROOT/pthreads/sync.c,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 sync.c
--- sync.c	1999/08/17 00:50:05	1.1.1.1
+++ sync.c	1999/08/18 01:09:41
@@ -128,6 +128,8 @@ pthread_join (pthread_t thread, void **v
 
       stat = WaitForSingleObject (thread->threadH, INFINITE);
 
+#if ! defined (__MINGW32__) || defined (__MSVCRT__)
+
       if (stat == WAIT_OBJECT_0)
 	{
 	  if (value_ptr != NULL
@@ -148,6 +150,24 @@ pthread_join (pthread_t thread, void **v
 	{
 	  result = ESRCH;
 	}
+
+#else /* __MINGW32__ && ! __MSVCRT__ */
+
+      /* If using CRTDLL, the thread may have exited, and endthread
+	 will have closed the handle. Also, begin/endthread pair
+	 does not allow for a exit code -- we'll force it to be
+	 always 0.  */
+
+      if (value_ptr != NULL)
+	*((DWORD*)(value_ptr)) = 0;
+      
+      /*
+       * The result of making multiple simultaneous calls to
+       * pthread_join() specifying the same target is undefined.
+       */
+      _pthread_threadDestroy (thread);
+
+#endif /* __MINGW32__ && ! __MSVCRT__ */
     }
 
   return (result);
Index: tests/join1.c
===================================================================
RCS file: /homes/khan/src/CVSROOT/pthreads/tests/join1.c,v
retrieving revision 1.1.1.1
diff -u -3 -p -r1.1.1.1 join1.c
--- tests/join1.c	1999/08/17 00:50:05	1.1.1.1
+++ tests/join1.c	1999/08/18 01:16:42
@@ -33,7 +33,12 @@ main(int argc, char * argv[])
 	for (i = 0; i < 4; i++)
 	  {
 	    assert(pthread_join(id[i], (void *) &result) == 0);
+#if ! defined (__MINGW32__) || defined (__MSVCRT__)
 	    assert(result == i);
+#else
+# warning pthread_join not fully supported in this configuration.
+	    assert(result == 0);
+#endif
 	  }
 
 	/* Success. */

Regards,
Mumit

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]