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]

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]