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; +} | 
