From 5e87a0d9bdd4c2c2ab0e45a6379b4df0f1471ffa Mon Sep 17 00:00:00 2001 From: rpj Date: Thu, 19 Aug 1999 05:26:02 +0000 Subject: 1999-08-19 Ross Johnson * private.c (_pthread_threadStart): Return exit status from the application thread startup routine. - Milan Gardian 1999-08-18 Ross Johnson * exit.c (pthread_exit): Put status into pthread_t->exitStatus - John Bossom * private.c (_pthread_threadStart): Set pthread->exitStatus on exit of try{} block. - John Bossom * sync.c (pthread_join): use pthread_exitStatus value if the thread exit doesn't return a value (for Mingw32 CRTDLL which uses endthread instead of _endthreadex). - John Bossom Tue Aug 17 20:17:58 CDT 1999 Mumit Khan * 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. Tue Aug 17 20:00:08 1999 Mumit Khan * Makefile.in (LD): Delete entry point. * acconfig.h (STDCALL): Delete unused macro. * configure.in: Remove test for STDCALL. * config.h.in: Regenerate. * errno.c (_errno): Fix self type. * pthread.h (PT_STDCALL): Move from here to * implement.h (PT_STDCALL): here. (_pthread_threadStart): Fix prototype. * private.c (_pthread_threadStart): Likewise. 1999-08-14 Ross Johnson * exit.c (pthread_exit): Don't call pthread_self() but get thread handle directly from TSD for efficiency. --- CONTRIBUTORS | 3 ++- ChangeLog | 41 ++++++++++++++++++++++++++++++++++++++++- Makefile.in | 2 +- acconfig.h | 2 -- config.h.in | 3 --- configure.in | 9 --------- create.c | 23 +++++++++++++++++++++++ errno.c | 2 +- exit.c | 10 +++++++++- implement.h | 12 ++++++++---- private.c | 30 ++++++++++++++++++++++++------ pthread.h | 6 ------ sync.c | 19 +++++++++++++++++++ tests/ChangeLog | 4 ++++ tests/Makefile | 3 ++- tests/join1.c | 5 +++++ tests/join2.c | 37 +++++++++++++++++++++++++++++++++++++ 17 files changed, 175 insertions(+), 36 deletions(-) create mode 100644 tests/join2.c diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 2fd2592..b4780bd 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -10,4 +10,5 @@ Kevin Ruland Kevin.Ruland@anheuser-busch.com Mike Russo miker@eai.com Mark E. Armstrong avail@pacbell.net Lorin Hochstein lmh@xiphos.ca -Peter Slacik Peter.Slacik@tatramed.sk \ No newline at end of file +Peter Slacik Peter.Slacik@tatramed.sk +Mumit Khan khan@xraylith.wisc.edu diff --git a/ChangeLog b/ChangeLog index 4655fc0..2e03c53 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,46 @@ +1999-08-19 Ross Johnson + + * private.c (_pthread_threadStart): Return exit status from + the application thread startup routine. + - Milan Gardian + +1999-08-18 Ross Johnson + + * exit.c (pthread_exit): Put status into pthread_t->exitStatus + - John Bossom + * private.c (_pthread_threadStart): Set pthread->exitStatus + on exit of try{} block. + - John Bossom + * sync.c (pthread_join): use pthread_exitStatus value if the + thread exit doesn't return a value (for Mingw32 CRTDLL + which uses endthread instead of _endthreadex). + - John Bossom + +Tue Aug 17 20:17:58 CDT 1999 Mumit Khan + + * 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. + +Tue Aug 17 20:00:08 1999 Mumit Khan + + * Makefile.in (LD): Delete entry point. + * acconfig.h (STDCALL): Delete unused macro. + * configure.in: Remove test for STDCALL. + * config.h.in: Regenerate. + * errno.c (_errno): Fix self type. + * pthread.h (PT_STDCALL): Move from here to + * implement.h (PT_STDCALL): here. + (_pthread_threadStart): Fix prototype. + * private.c (_pthread_threadStart): Likewise. + 1999-08-14 Ross Johnson * exit.c (pthread_exit): Don't call pthread_self() but - get thread handle directly for efficiency. + get thread handle directly from TSD for efficiency. 1999-08-12 Ross Johnson diff --git a/Makefile.in b/Makefile.in index 2844862..518061e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -24,7 +24,7 @@ CC = g++ AR = ar -LD = gcc -mdll -e _DllMain@12 +LD = gcc -mdll OPT = -g -O2 diff --git a/acconfig.h b/acconfig.h index dab82ba..cf5e6ba 100644 --- a/acconfig.h +++ b/acconfig.h @@ -1,5 +1,3 @@ /* Do we know about the C type sigset_t? */ #undef HAVE_SIGSET_T -/* Do we have the `_stdcall' keyword? */ -#undef STDCALL diff --git a/config.h.in b/config.h.in index 920b9c4..6671c7f 100644 --- a/config.h.in +++ b/config.h.in @@ -3,9 +3,6 @@ /* Do we know about the C type sigset_t? */ #undef HAVE_SIGSET_T -/* Do we have the `_stdcall' keyword? */ -#undef STDCALL - /* Define if you have the header file. */ #undef HAVE_SIGNAL_H diff --git a/configure.in b/configure.in index 76c78ea..0896edb 100644 --- a/configure.in +++ b/configure.in @@ -15,15 +15,6 @@ then AC_DEFINE(HAVE_SIGSET_T) fi fi -AC_CACHE_CHECK(for _stdcall keyword, p32_cv_stdcall, - AC_TRY_COMPILE( ,[int __stdcall foo();], - p32_cv_stdcall=yes, p32_cv_stdcall=no)) - -if test x$p32_cv_stdcall = xyes ; then - AC_DEFINE(STDCALL, __stdcall) -else - AC_DEFINE(STDCALL,) -fi AC_CHECK_HEADERS(windows.h,,AC_MSG_WARN([Target system must be Win32])) AC_OUTPUT(Makefile) diff --git a/create.c b/create.c index e085179..426ad9a 100644 --- a/create.c +++ b/create.c @@ -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 */ @@ -134,6 +136,27 @@ pthread_create (pthread_t * tid, (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; /* diff --git a/errno.c b/errno.c index 69fdddd..c457dd7 100644 --- a/errno.c +++ b/errno.c @@ -59,7 +59,7 @@ static int reallyBad = ENOMEM; int * _errno( void ) { - pthread_t *self; + pthread_t self; int *result; if( ( self = pthread_self() ) == NULL ) diff --git a/exit.c b/exit.c index 18592a2..32468d9 100644 --- a/exit.c +++ b/exit.c @@ -61,12 +61,17 @@ pthread_exit (void *value_ptr) */ self = (pthread_t) pthread_getspecific (_pthread_selfThreadKey); + self->exitStatus = value_ptr; if (self == NULL || self->implicit) { _pthread_callUserDestroyRoutines(self); +#if ! defined (__MINGW32__) || defined (__MSVCRT__) _endthreadex ((unsigned) value_ptr); +#else + _endthread (); +#endif /* Never reached */ } @@ -90,7 +95,6 @@ pthread_exit (void *value_ptr) #ifdef __cplusplus - self->exceptionInformation = value_ptr; throw Pthread_exception_exit(); #else /* ! __cplusplus */ @@ -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 */ diff --git a/implement.h b/implement.h index f18c7d5..11d5b1b 100644 --- a/implement.h +++ b/implement.h @@ -27,6 +27,8 @@ #ifndef _IMPLEMENT_H #define _IMPLEMENT_H +#define PT_STDCALL __stdcall + #include typedef enum { @@ -77,9 +79,6 @@ struct pthread_t_ { sigset_t sigmask; #endif /* HAVE_SIGSET_T */ int implicit:1; -#ifdef __cplusplus - void * exceptionInformation; -#endif void *keys; }; @@ -319,7 +318,12 @@ void _pthread_threadDestroy (pthread_t tid); void _pthread_cleanupStack (void); -void *_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); diff --git a/private.c b/private.c index 3c533f1..58bf148 100644 --- a/private.c +++ b/private.c @@ -159,7 +159,11 @@ ExceptionFilter (EXCEPTION_POINTERS * ep, DWORD * ei) #endif /* _MSC_VER */ -void * +#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 * threadParms) 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); @@ -189,8 +198,7 @@ _pthread_threadStart (ThreadParms * threadParms) /* * Run the caller's routine; */ - (*start) (arg); - status = (void *) 0; + status = (*start) (arg); } __except (ExceptionFilter(GetExceptionInformation(), ei)) { @@ -230,7 +238,7 @@ _pthread_threadStart (ThreadParms * threadParms) * Run the caller's routine; */ (*start) (arg); - status = (void *) 0; + status = self->exitStatus = (void *) 0; } catch (Pthread_exception_cancel) { @@ -244,7 +252,7 @@ _pthread_threadStart (ThreadParms * threadParms) /* * Thread was exited via pthread_exit(). */ - status = self->exceptionInformation; + status = self->exitStatus; } catch (...) { @@ -270,12 +278,19 @@ _pthread_threadStart (ThreadParms * threadParms) _pthread_callUserDestroyRoutines(self); +#if ! defined (__MINGW32__) || defined (__MSVCRT__) _endthreadex ((unsigned) status); +#else + _endthread (); +#endif /* * Never reached. */ - return (status); + +#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); } diff --git a/pthread.h b/pthread.h index 29961f2..af982b3 100644 --- a/pthread.h +++ b/pthread.h @@ -253,12 +253,6 @@ struct timespec { #define FALSE 0 #endif /* !TRUE */ -#ifdef __MINGW32__ -#define PT_STDCALL -#else -#define PT_STDCALL __stdcall -#endif - /* * This should perhaps be in autoconf or * possibly fixed in Mingw32 to diff --git a/sync.c b/sync.c index ac4c11f..06dffd9 100644 --- a/sync.c +++ b/sync.c @@ -128,6 +128,8 @@ pthread_join (pthread_t thread, void **value_ptr) stat = WaitForSingleObject (thread->threadH, INFINITE); +#if ! defined (__MINGW32__) || defined (__MSVCRT__) + if (stat == WAIT_OBJECT_0) { if (value_ptr != NULL @@ -148,6 +150,23 @@ pthread_join (pthread_t thread, void **value_ptr) { result = ESRCH; } + +#else /* __MINGW32__ && ! __MSVCRT__ */ + + /* + * If using CRTDLL, the thread may have exited, and endthread + * will have closed the handle. + */ + if (value_ptr != NULL) + *value_ptr = self->exitStatus; + + /* + * The result of making multiple simultaneous calls to + * pthread_join() specifying the same target is undefined. + */ + _pthread_threadDestroy (thread); + +#endif /* __MINGW32__ && ! __MSVCRT__ */ } return (result); diff --git a/tests/ChangeLog b/tests/ChangeLog index ac229c7..3d5163b 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,7 @@ +Aug 19 1999 Ross Johnson + + * join2.c: New test. + Wed Aug 12 1999 Ross Johnson * Makefile (LIBS): Add -L. diff --git a/tests/Makefile b/tests/Makefile index 7c60452..60bd014 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -38,7 +38,7 @@ COPYFILES = $(HDR) $(LIB) $(DLL) TESTS = mutex1 condvar1 condvar2 exit1 create1 equal1 \ exit2 exit3 \ - join1 mutex2 mutex3 \ + join1 join2 mutex2 mutex3 \ count1 once1 tsd1 self1 self2 eyal1 \ condvar3 condvar4 condvar5 condvar6 \ errno1 @@ -60,6 +60,7 @@ equal1.pass: create1.pass exit2.pass: create1.pass exit3.pass: create1.pass join1.pass: create1.pass +join2.pass: create1.pass count1.pass: join1.pass once1.pass: create1.pass tsd1.pass: join1.pass diff --git a/tests/join1.c b/tests/join1.c index f6240de..f206c0b 100644 --- a/tests/join1.c +++ b/tests/join1.c @@ -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. */ diff --git a/tests/join2.c b/tests/join2.c new file mode 100644 index 0000000..281a0df --- /dev/null +++ b/tests/join2.c @@ -0,0 +1,37 @@ +/* + * Test for pthread_join() returning return value from threads. + * + * Depends on API functions: pthread_create(). + */ + +#include "test.h" + +void * +func(void * arg) +{ + Sleep(1000); + return arg; +} + +int +main(int argc, char * argv[]) +{ + pthread_t id[4]; + int i; + int result; + + /* Create a few threads and then exit. */ + for (i = 0; i < 4; i++) + { + assert(pthread_create(&id[i], NULL, func, (void *) i) == 0); + } + + for (i = 0; i < 4; i++) + { + assert(pthread_join(id[i], (void *) &result) == 0); + assert(result == i); + } + + /* Success. */ + return 0; +} -- cgit v1.2.3