diff options
-rw-r--r-- | CONTRIBUTORS | 3 | ||||
-rw-r--r-- | ChangeLog | 41 | ||||
-rw-r--r-- | Makefile.in | 2 | ||||
-rw-r--r-- | acconfig.h | 2 | ||||
-rw-r--r-- | config.h.in | 3 | ||||
-rw-r--r-- | configure.in | 9 | ||||
-rw-r--r-- | create.c | 23 | ||||
-rw-r--r-- | errno.c | 2 | ||||
-rw-r--r-- | exit.c | 10 | ||||
-rw-r--r-- | implement.h | 12 | ||||
-rw-r--r-- | private.c | 30 | ||||
-rw-r--r-- | pthread.h | 6 | ||||
-rw-r--r-- | sync.c | 19 | ||||
-rw-r--r-- | tests/ChangeLog | 4 | ||||
-rw-r--r-- | tests/Makefile | 3 | ||||
-rw-r--r-- | tests/join1.c | 5 | ||||
-rw-r--r-- | tests/join2.c | 37 |
17 files changed, 175 insertions, 36 deletions
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 @@ -1,7 +1,46 @@ +1999-08-19 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * private.c (_pthread_threadStart): Return exit status from + the application thread startup routine. + - Milan Gardian <mg@tatramed.sk> + +1999-08-18 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * exit.c (pthread_exit): Put status into pthread_t->exitStatus + - John Bossom <john.Bossom@cognos.com> + * private.c (_pthread_threadStart): Set pthread->exitStatus + on exit of try{} block. + - John Bossom <john.Bossom@cognos.com> + * 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 <john.Bossom@cognos.com> + +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. + +Tue Aug 17 20:00:08 1999 Mumit Khan <khan@xraylith.wisc.edu> + + * 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 <rpj@ixobrychus.canberra.edu.au> * 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 <rpj@ixobrychus.canberra.edu.au> 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 @@ -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 <signal.h> 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) @@ -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; /* @@ -59,7 +59,7 @@ static int reallyBad = ENOMEM; int * _errno( void ) { - pthread_t *self; + pthread_t self; int *result; if( ( self = pthread_self() ) == NULL ) @@ -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 <semaphore.h> 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); @@ -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); } @@ -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 @@ -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 <rpj@ixobrychus.canberra.edu.au> + + * join2.c: New test. + Wed Aug 12 1999 Ross Johnson <rpj@ixobrychus.canberra.edu.au> * 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; +} |