summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS3
-rw-r--r--ChangeLog41
-rw-r--r--Makefile.in2
-rw-r--r--acconfig.h2
-rw-r--r--config.h.in3
-rw-r--r--configure.in9
-rw-r--r--create.c23
-rw-r--r--errno.c2
-rw-r--r--exit.c10
-rw-r--r--implement.h12
-rw-r--r--private.c30
-rw-r--r--pthread.h6
-rw-r--r--sync.c19
-rw-r--r--tests/ChangeLog4
-rw-r--r--tests/Makefile3
-rw-r--r--tests/join1.c5
-rw-r--r--tests/join2.c37
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
diff --git a/ChangeLog b/ChangeLog
index 4655fc0..2e03c53 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
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 <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)
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 <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);
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 <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;
+}