From cc29ad943903e9b8dba96cd978cb126f79f73e38 Mon Sep 17 00:00:00 2001 From: rpj Date: Tue, 2 Feb 1999 02:01:56 +0000 Subject: Mods to compile under Mingw32 egcs. Tue Feb 2 18:07:43 1999 Ross Johnson * implement.h: Add #include . Change sem_t to _pthread_sem_t. Various patches by Kevin Ruland * signal.c (pthread_sigmask): Add and modify casts. Reverse LHS/RHS bitwise assignments. * pthread.h: Remove #include . (_PTHREAD_ATTR_VALID): Add cast. (struct pthread_t_): Add sigmask element. * dll.c: Add "extern C" for DLLMain. (DllMain): Add cast. * create.c (pthread_create): Set sigmask in thread. * condvar.c: Remove #include. Change sem_* to _pthread_sem_*. * attr.c: Changed #include. * Makefile.in: Additional targets and changes to build the library as a DLL. Fri Jan 29 11:56:28 1999 Ross Johnson * Makefile.in (OBJS): Add semaphore.o to list. * semaphore.c (_pthread_sem_timedwait): Move from private.c. Rename sem_* to _pthread_sem_*. * pthread.h (pthread_cond_t): Change type of sem_t. _POSIX_SEMAPHORES no longer defined. * semaphore.h: Contents moved to implement.h. Removed from source tree. * implement.h: Add semaphore function prototypes and ename all functions to prepend '_pthread_'. They are now private to the pthreads-win32 implementation. * private.c: Change #warning. Move _pthread_sem_timedwait() to semaphore.c. * cleanup.c: Change #warning. * misc.c: Remove #include * pthread.def: Cleanup CVS merge conflicts. * global.c: Ditto. * ChangeLog: Ditto. * cleanup.c: Ditto. --- ChangeLog | 58 +++++++++++++++++++++++++++++++++ Makefile.in | 24 +++++++++++--- attr.c | 3 +- cleanup.c | 14 ++++---- condvar.c | 14 ++++---- create.c | 7 ++++ dll.c | 15 +++++++++ implement.h | 17 +++++++++- misc.c | 2 -- mutex.c | 14 ++++---- private.c | 79 +++----------------------------------------- pthread.def | 6 ++-- pthread.h | 58 +++++++++++++-------------------- semaphore.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++--------- semaphore.h | 52 ----------------------------- signal.c | 16 ++++----- 16 files changed, 266 insertions(+), 219 deletions(-) delete mode 100644 semaphore.h diff --git a/ChangeLog b/ChangeLog index b12ecd3..2615bc0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,61 @@ +Tue Feb 2 18:07:43 1999 Ross Johnson + + * implement.h: Add #include . + Change sem_t to _pthread_sem_t. + + Various patches by Kevin Ruland + + * signal.c (pthread_sigmask): Add and modify casts. + Reverse LHS/RHS bitwise assignments. + + * pthread.h: Remove #include . + (_PTHREAD_ATTR_VALID): Add cast. + (struct pthread_t_): Add sigmask element. + + * dll.c: Add "extern C" for DLLMain. + (DllMain): Add cast. + + * create.c (pthread_create): Set sigmask in thread. + + * condvar.c: Remove #include. Change sem_* to _pthread_sem_*. + + * attr.c: Changed #include. + + * Makefile.in: Additional targets and changes to build the library + as a DLL. + +Fri Jan 29 11:56:28 1999 Ross Johnson + + * Makefile.in (OBJS): Add semaphore.o to list. + + * semaphore.c (_pthread_sem_timedwait): Move from private.c. + Rename sem_* to _pthread_sem_*. + + * pthread.h (pthread_cond_t): Change type of sem_t. + _POSIX_SEMAPHORES no longer defined. + + * semaphore.h: Contents moved to implement.h. + Removed from source tree. + + * implement.h: Add semaphore function prototypes and ename all + functions to prepend '_pthread_'. They are + now private to the pthreads-win32 implementation. + + * private.c: Change #warning. + Move _pthread_sem_timedwait() to semaphore.c. + + * cleanup.c: Change #warning. + + * misc.c: Remove #include + + * pthread.def: Cleanup CVS merge conflicts. + + * global.c: Ditto. + + * ChangeLog: Ditto. + + * cleanup.c: Ditto. + Sun Jan 24 01:34:52 1999 Ross Johnson * semaphore.c (sem_wait): Remove second arg to diff --git a/Makefile.in b/Makefile.in index a5dea55..b7db1af 100644 --- a/Makefile.in +++ b/Makefile.in @@ -6,18 +6,34 @@ CFLAGS = -g -I. -DHAVE_CONFIG_H -Wall # Cygwin G++ #CFLAGS = -fhandle-exceptions -I. -DHAVE_CONFIG_H -Wall +LD = gcc -mdll -e _DllMain@12 + OBJS = attr.o cancel.o cleanup.o condvar.o create.o dll.o \ exit.o fork.o global.o misc.o mutex.o private.o sched.o \ - signal.o sync.o tsd.o + semaphore.o signal.o sync.o tsd.o INCL = implement.h pthread.h windows.h +DLL = pthread.dll + LIB = libpthread32.a -all: $(LIB) +all: $(DLL) $(LIB): $(OBJS) - $(AR) r $(LIB) $(OBJS) + $(AR) r $@ $^ + +.SUFFIXES: .dll + +$(DLL): $(OBJS) + $(LD) -o $@ $^ -Wl,--base-file,$*.base + dlltool --base-file=$*.base --def $*.def --output-exp $*.exp --dllname $@ + $(LD) -o $@ $^ -Wl,--base-file,$*.base,$*.exp + dlltool --base-file=$*.base --def $*.def --output-exp $*.exp --dllname $@ + $(LD) -o $@ $^ -Wl,$*.exp + dlltool --def $*.def --output-lib $*.lib --dllname $@ clean: - -rm $(LIB) *.o + -rm *~ + -rm $(LIB) *.o *.exe + -rm $(DLL) $(DLL:.dll=.base) $(DLL:.dll=.exp) $(DLL:.dll=.lib) diff --git a/attr.c b/attr.c index e0778ac..edf6ff1 100644 --- a/attr.c +++ b/attr.c @@ -5,8 +5,7 @@ * This translation unit implements operations on thread attribute objects. */ -#include -#include +#include #include "pthread.h" #include "implement.h" diff --git a/cleanup.c b/cleanup.c index 3a1613c..012b82e 100644 --- a/cleanup.c +++ b/cleanup.c @@ -6,7 +6,11 @@ * threads. */ -#include +#if !defined(_MSC_VER) && !defined(__cplusplus) && defined(__GNUC__) + +#warning Compile __FILE__ as C++ or thread cancellation will not work properly. + +#endif /* !_MSC_VER && !__cplusplus && __GNUC__ */ #include "pthread.h" #include "implement.h" @@ -91,10 +95,6 @@ _pthread_pop_cleanup (int execute) #else /* __cplusplus */ -#if defined(__GNUC__) -#warning Compile __FILE__ as C++ or thread cancellation will not work properly. -#endif - /* * Run the caller's cleanup routine and FIXME: hope for the best. */ @@ -110,7 +110,7 @@ _pthread_pop_cleanup (int execute) pthread_setspecific (_pthread_cleanupKey, (void *) cleanup->prev); -#endif +#endif /* !_MSC_VER && !__cplusplus */ } @@ -170,7 +170,7 @@ _pthread_push_cleanup (_pthread_cleanup_t * cleanup, cleanup->prev = (_pthread_cleanup_t *) pthread_getspecific (_pthread_cleanupKey); -#endif +#endif /* !_MSC_VER && !__cplusplus */ pthread_setspecific (_pthread_cleanupKey, (void *) cleanup); diff --git a/condvar.c b/condvar.c index 37d92e6..891705d 100644 --- a/condvar.c +++ b/condvar.c @@ -9,8 +9,6 @@ * Code contributed by John E. Bossom . */ -#include - #include "pthread.h" #include "implement.h" @@ -308,7 +306,7 @@ pthread_cond_init (pthread_cond_t * cond, const pthread_condattr_t * attr) cv->waiters = 0; cv->wasBroadcast = FALSE; - if (sem_init (&(cv->sema), 0, 1) != 0) + if (_pthread_sem_init (&(cv->sema), 0, 1) != 0) { goto FAIL0; } @@ -341,7 +339,7 @@ FAIL2: (void) pthread_mutex_destroy (&(cv->waitersLock)); FAIL1: - (void) sem_destroy (&(cv->sema)); + (void) _pthread_sem_destroy (&(cv->sema)); free (cv); cv = NULL; @@ -388,7 +386,7 @@ pthread_cond_destroy (pthread_cond_t * cond) { cv = *cond; - (void) sem_destroy (&(cv->sema)); + (void) _pthread_sem_destroy (&(cv->sema)); (void) pthread_mutex_destroy (&(cv->waitersLock)); (void) CloseHandle (cv->waitersDone); @@ -420,7 +418,7 @@ cond_timedwait (pthread_cond_t * cond, * We keep the lock held just long enough to increment the count of * waiters by one (above). * Note that we can't keep it held across the - * call to sem_wait since that will deadlock other calls + * call to _pthread_sem_wait since that will deadlock other calls * to pthread_cond_signal */ if ((result = pthread_mutex_unlock (mutex)) == 0) @@ -656,7 +654,7 @@ pthread_cond_signal (pthread_cond_t * cond) if (cv->waiters > 0) { - result = sem_post (&(cv->sema)); + result = _pthread_sem_post (&(cv->sema)); } return (result); @@ -713,7 +711,7 @@ pthread_cond_broadcast (pthread_cond_t * cond) for (i = cv->waiters; i > 0 && result == 0; i--) { - result = sem_post (&(cv->sema)); + result = _pthread_sem_post (&(cv->sema)); } if (cv->waiters > 0 && result == 0) diff --git a/create.c b/create.c index c017b61..292097d 100644 --- a/create.c +++ b/create.c @@ -90,6 +90,13 @@ pthread_create (pthread_t * tid, { stackSize = (*attr)->stacksize; thread->detachState = (*attr)->detachstate; + +#if HAVE_SIGSET_T + + thread->sigmask = (*attr)->sigmask; + +#endif /* HAVE_SIGSET_T */ + } else { diff --git a/dll.c b/dll.c index 7ebfd5e..b440500 100644 --- a/dll.c +++ b/dll.c @@ -29,6 +29,20 @@ static HINSTANCE _pthread_h_kernel32; #pragma warning( disable : 4100 ) #endif +#ifdef __cplusplus +/* + * Dear c++: Please don't mangle this name. -thanks + */ +extern "C" +{ +#endif /* __cplusplus */ + + BOOL WINAPI DllMain( HINSTANCE, DWORD, LPVOID); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + BOOL WINAPI DllMain ( HINSTANCE hinstDll, @@ -50,6 +64,7 @@ DllMain ( /* Load KERNEL32 and try to get address of TryEnterCriticalSection */ _pthread_h_kernel32 = LoadLibrary(TEXT("KERNEL32.DLL")); _pthread_try_enter_critical_section = + (BOOL (PT_STDCALL *)(LPCRITICAL_SECTION)) GetProcAddress(_pthread_h_kernel32, (LPCSTR) "TryEnterCriticalSection"); break; diff --git a/implement.h b/implement.h index 75ca6f6..ca138cd 100644 --- a/implement.h +++ b/implement.h @@ -154,6 +154,8 @@ extern pthread_key_t _pthread_cleanupKey; extern CRITICAL_SECTION _pthread_mutex_test_init_lock; +#include + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -183,7 +185,20 @@ int _pthread_tkAssocCreate (ThreadKeyAssoc ** assocP, void _pthread_tkAssocDestroy (ThreadKeyAssoc * assoc); -int _pthread_sem_timedwait (sem_t * sem, const struct timespec * abstime); +int _pthread_sem_init (_pthread_sem_t * sem, + int pshared, + unsigned int value); + +int _pthread_sem_destroy (_pthread_sem_t * sem); + +int _pthread_sem_trywait (_pthread_sem_t * sem); + +int _pthread_sem_wait (_pthread_sem_t * sem); + +int _pthread_sem_timedwait (_pthread_sem_t * sem, + const struct timespec * abstime); + +int _pthread_sem_post (_pthread_sem_t * sem); #ifdef __cplusplus } diff --git a/misc.c b/misc.c index f57d738..8d353c1 100644 --- a/misc.c +++ b/misc.c @@ -5,8 +5,6 @@ * This translation unit implements miscellaneous thread functions. */ -#include - #include "pthread.h" #include "implement.h" diff --git a/mutex.c b/mutex.c index 1a037f0..cca8fa3 100644 --- a/mutex.c +++ b/mutex.c @@ -42,20 +42,20 @@ _mutex_check_need_init(pthread_mutex_t *mutex) * the number of processors + 1. * * We need to maintain the following per-mutex state independently: - * - mutex staticinit (true iff static mutex and still + * - mutex staticinit (true iff mutex is static and still * needs to be initialised) * - mutex valid (false iff mutex has been destroyed) * - * For example, a mutex initialised by PTHREAD_MUTEX_INITIALIZER - * in this implementation will be valid but uninitialised until the thread - * attempts to lock it. It can also be destroyed (made invalid) before - * ever being locked. + * For example, in this implementation a mutex initialised by + * PTHREAD_MUTEX_INITIALIZER will be 'valid' but uninitialised until + * the thread attempts to lock it. It can also be destroyed (made invalid) + * before ever being locked. */ EnterCriticalSection(&_pthread_mutex_test_init_lock); /* - * We got here because staticinit tested true. - * Check staticinit again inside the critical section + * We got here because staticinit tested true, possibly under race + * conditions. Check staticinit again inside the critical section * and only initialise if the mutex is valid (not been destroyed). * If a static mutex has been destroyed, the application can * re-initialise it only by calling pthread_mutex_init() diff --git a/private.c b/private.c index 615271d..88a71ee 100644 --- a/private.c +++ b/private.c @@ -6,7 +6,11 @@ * the implementation and may be used throughout it. */ -#include +#if !defined(_MSC_VER) && !defined(__cplusplus) && defined(__GNUC__) + +#warning Compile __FILE__ as C++ or thread cancellation will not work properly. + +#endif /* !_MSC_VER && !__cplusplus && __GNUC__ */ #include "pthread.h" #include "implement.h" @@ -182,10 +186,6 @@ _pthread_threadStart (ThreadParms * threadParms) #else /* __cplusplus */ -#if defined(__CYGWIN__) || defined(__CYGWIN32__) -#warning File __FILE__, Line __LINE__: Cancelation not supported under C. -#endif - /* * Run the caller's routine; */ @@ -488,73 +488,4 @@ _pthread_callUserDestroyRoutines (pthread_t thread) /* */ -int -_pthread_sem_timedwait (sem_t * sem, const struct timespec * abstime) - /* - * ------------------------------------------------------ - * DOCPUBLIC - * This function waits on a semaphore possibly until - * 'abstime' time. - * - * PARAMETERS - * sem - * pointer to an instance of sem_t - * - * abstime - * pointer to an instance of struct timespec - * - * DESCRIPTION - * This function waits on a semaphore. If the - * semaphore value is greater than zero, it decreases - * its value by one. If the semaphore value is zero, then - * the calling thread (or process) is blocked until it can - * successfully decrease the value or until interrupted by - * a signal. - * - * If 'abstime' is a NULL pointer then this function will - * block until it can successfully decrease the value or - * until interrupted by a signal. - * - * RESULTS - * 0 successfully decreased semaphore, - * EINVAL 'sem' is not a valid semaphore, - * ENOSYS semaphores are not supported, - * EINTR the function was interrupted by a signal, - * EDEADLK a deadlock condition was detected. - * ETIMEDOUT abstime elapsed before success. - * - * ------------------------------------------------------ - */ -{ - struct _timeb currSysTime; - const DWORD NANOSEC_PER_MILLISEC = 1000000; - const DWORD MILLISEC_PER_SEC = 1000; - DWORD milliseconds; - - if (abstime == NULL) - { - milliseconds = INFINITE; - } - else - { - /* - * Calculate timeout as milliseconds from current system time. - */ - - /* get current system time */ - _ftime(&currSysTime); - - /* subtract current system time from abstime */ - milliseconds = (abstime->tv_sec - currSysTime.time) * MILLISEC_PER_SEC; - milliseconds += (abstime->tv_nsec / NANOSEC_PER_MILLISEC) - - currSysTime.millitm; - } - - return ((sem == NULL) - ? EINVAL - : pthreadCancelableTimedWait (*sem, milliseconds) - ); - -} /* _pthread_sem_timedwait */ - diff --git a/pthread.def b/pthread.def index d8f950f..542f07b 100644 --- a/pthread.def +++ b/pthread.def @@ -1,5 +1,5 @@ ; pthread.def -; Last updated: $Date: 1999/01/23 06:59:02 $ +; Last updated: $Date: 1999/02/02 02:02:08 $ ; Currently unimplemented functions are commented out. @@ -24,8 +24,8 @@ pthread_attr_setschedparam ;pthread_attr_setstackaddr pthread_attr_setstacksize pthread_cancel -;pthread_cleanup_pop -;pthread_cleanup_push +pthread_cleanup_pop +pthread_cleanup_push pthread_condattr_destroy pthread_condattr_getpshared pthread_condattr_init diff --git a/pthread.h b/pthread.h index d090e43..e0fc11f 100644 --- a/pthread.h +++ b/pthread.h @@ -15,6 +15,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#if !defined( PTHREAD_H ) +#define PTHREAD_H + /* * ------------------------------------------------------------- * @@ -171,8 +174,6 @@ * * ------------------------------------------------------------- */ -#if !defined( PTHREAD_H ) -#define PTHREAD_H #ifdef _MSC_VER /* @@ -249,7 +250,6 @@ struct timespec { #endif /* !TRUE */ -#include /* #include */ #ifdef __MINGW32__ @@ -278,16 +278,6 @@ extern "C" * POSIX 1003.1c-1995 Options * =========================== * - * _POSIX_SEMAPHORES - * Semaphores come from POSIX.1b (POSIX 1003.1b-1993) - * rather than from PThreads. This macro indicates - * that POSIX Semaphores are supported: - * sem_destroy - * sem_init - * sem_wait - * sem_trywait - * sem_post - * * _POSIX_THREADS (set) * If set, you can use threads * @@ -381,7 +371,6 @@ extern "C" * POSIX Options */ #define _POSIX_THREADS -#define _POSIX_SEMAPHORES #define _POSIX_THREAD_SAFE_FUNCTIONS #define _POSIX_THREAD_ATTR_STACKSIZE @@ -567,6 +556,9 @@ struct pthread_t_ { int cancelState; int cancelType; HANDLE cancelEvent; +#if HAVE_SIGSET_T + sigset_t sigmask; +#endif /* HAVE_SIGSET_T */ int implicit:1; void *keys; }; @@ -575,7 +567,7 @@ struct pthread_t_ { /* * Special value to mark attribute objects as valid. */ -#define _PTHREAD_ATTR_VALID 0xC4C0FFEE +#define _PTHREAD_ATTR_VALID ((unsigned long) 0xC4C0FFEE) struct pthread_attr_t_ { unsigned long valid; @@ -611,11 +603,13 @@ struct pthread_key_t_ { }; +typedef HANDLE _pthread_sem_t; + struct pthread_cond_t_ { long waiters; /* # waiting threads */ pthread_mutex_t waitersLock; /* Mutex that guards access to waiter count */ - sem_t sema; /* Queue up threads waiting for the + _pthread_sem_t sema; /* Queue up threads waiting for the condition to become signaled */ HANDLE waitersDone; /* An auto reset event used by the broadcast/signal thread to wait @@ -668,19 +662,22 @@ struct pthread_once_t_ { * C++ */ +typedef struct _pthread_cleanup_t _pthread_cleanup_t; + +struct _pthread_cleanup_t +{ + void (*routine) (void *); + void *arg; +#if !defined(_MSC_VER) && !defined(__cplusplus) + _pthread_cleanup_t *prev; +#endif +}; + #ifdef _MSC_VER /* * WIN32 SEH version of cancel cleanup. */ - typedef struct _pthread_cleanup_t _pthread_cleanup_t; - - struct _pthread_cleanup_t - { - void (*routine) (void *); - void *arg; - }; - #define pthread_cleanup_push( _rout, _arg ) \ { \ _pthread_cleanup_t _cleanup; \ @@ -709,15 +706,6 @@ struct pthread_once_t_ { * C implementation of PThreads cancel cleanup */ - typedef struct _pthread_cleanup_t _pthread_cleanup_t; - - struct _pthread_cleanup_t - { - void (*routine) (void *); - void *arg; - _pthread_cleanup_t *prev; - }; - #define pthread_cleanup_push( _rout, _arg ) \ { \ _pthread_cleanup_t _cleanup; \ @@ -733,8 +721,6 @@ struct pthread_once_t_ { /* * C++ version of cancel cleanup. * - John E. Bossom. - * - * Emulate try-finally behaviour. */ class PThreadCleanup { @@ -1013,8 +999,10 @@ int pthreadCancelableTimedWait (HANDLE waitHandle, DWORD timeout); * Only provide function mappings for functions that * actually exist on WIN32. */ +#if !defined(__MINGW32__) #define strtok_r( _s, _sep, _lasts ) \ ( *(_lasts) = strtok( (_s), (_sep) ) ) +#endif /* !__MINGW32__ */ #define asctime_r( _tm, _buf ) \ ( strcpy( (_buf), asctime( (_tm) ) ), \ diff --git a/semaphore.c b/semaphore.c index 9645379..e682201 100644 --- a/semaphore.c +++ b/semaphore.c @@ -34,14 +34,16 @@ * * ------------------------------------------------------------- */ -#include -#include -#include "semaphore.h" +#include +#include + +#include +#include "implement.h" int -sem_init (sem_t * sem, int pshared, unsigned int value) +_pthread_sem_init (_pthread_sem_t * sem, int pshared, unsigned int value) /* * ------------------------------------------------------ * DOCPUBLIC @@ -50,7 +52,7 @@ sem_init (sem_t * sem, int pshared, unsigned int value) * * PARAMETERS * sem - * pointer to an instance of sem_t + * pointer to an instance of _pthread_sem_t * * pshared * if zero, this semaphore may only be shared between @@ -90,7 +92,7 @@ sem_init (sem_t * sem, int pshared, unsigned int value) { /* * NOTE: Taking advantage of the fact that - * sem_t is a simple structure with one entry; + * _pthread_sem_t is a simple structure with one entry; * We don't have to allocate it... */ *sem = CreateSemaphore ( @@ -111,7 +113,7 @@ sem_init (sem_t * sem, int pshared, unsigned int value) int -sem_destroy (sem_t * sem) +_pthread_sem_destroy (_pthread_sem_t * sem) /* * ------------------------------------------------------ * DOCPUBLIC @@ -119,7 +121,7 @@ sem_destroy (sem_t * sem) * * PARAMETERS * sem - * pointer to an instance of sem_t + * pointer to an instance of _pthread_sem_t * * DESCRIPTION * This function destroys an unnamed semaphore. @@ -144,7 +146,7 @@ sem_destroy (sem_t * sem) int -sem_trywait (sem_t * sem) +_pthread_sem_trywait (_pthread_sem_t * sem) /* * ------------------------------------------------------ * DOCPUBLIC @@ -152,7 +154,7 @@ sem_trywait (sem_t * sem) * * PARAMETERS * sem - * pointer to an instance of sem_t + * pointer to an instance of _pthread_sem_t * * DESCRIPTION * This function tries to wait on a semaphore. If the @@ -181,7 +183,7 @@ sem_trywait (sem_t * sem) int -sem_wait (sem_t * sem) +_pthread_sem_wait (_pthread_sem_t * sem) /* * ------------------------------------------------------ * DOCPUBLIC @@ -189,7 +191,7 @@ sem_wait (sem_t * sem) * * PARAMETERS * sem - * pointer to an instance of sem_t + * pointer to an instance of _pthread_sem_t * * DESCRIPTION * This function waits on a semaphore. If the @@ -219,7 +221,81 @@ sem_wait (sem_t * sem) int -sem_post (sem_t * sem) +_pthread_sem_timedwait (_pthread_sem_t * sem, const struct timespec * abstime) + /* + * ------------------------------------------------------ + * DOCPUBLIC + * This function waits on a semaphore possibly until + * 'abstime' time. + * + * PARAMETERS + * sem + * pointer to an instance of _pthread_sem_t + * + * abstime + * pointer to an instance of struct timespec + * + * DESCRIPTION + * This function waits on a semaphore. If the + * semaphore value is greater than zero, it decreases + * its value by one. If the semaphore value is zero, then + * the calling thread (or process) is blocked until it can + * successfully decrease the value or until interrupted by + * a signal. + * + * If 'abstime' is a NULL pointer then this function will + * block until it can successfully decrease the value or + * until interrupted by a signal. + * + * RESULTS + * 0 successfully decreased semaphore, + * EINVAL 'sem' is not a valid semaphore, + * ENOSYS semaphores are not supported, + * EINTR the function was interrupted by a signal, + * EDEADLK a deadlock condition was detected. + * ETIMEDOUT abstime elapsed before success. + * + * ------------------------------------------------------ + */ +{ +#if defined(__MINGW32__) + struct timeb currSysTime; +#else + struct _timeb currSysTime; +#endif + const DWORD NANOSEC_PER_MILLISEC = 1000000; + const DWORD MILLISEC_PER_SEC = 1000; + DWORD milliseconds; + + if (abstime == NULL) + { + milliseconds = INFINITE; + } + else + { + /* + * Calculate timeout as milliseconds from current system time. + */ + + /* get current system time */ + _ftime(&currSysTime); + + /* subtract current system time from abstime */ + milliseconds = (abstime->tv_sec - currSysTime.time) * MILLISEC_PER_SEC; + milliseconds += (abstime->tv_nsec / NANOSEC_PER_MILLISEC) - + currSysTime.millitm; + } + + return ((sem == NULL) + ? EINVAL + : pthreadCancelableTimedWait (*sem, milliseconds) + ); + +} /* _pthread_sem_timedwait */ + + +int +_pthread_sem_post (_pthread_sem_t * sem) /* * ------------------------------------------------------ * DOCPUBLIC @@ -227,7 +303,7 @@ sem_post (sem_t * sem) * * PARAMETERS * sem - * pointer to an instance of sem_t + * pointer to an instance of _pthread_sem_t * * DESCRIPTION * This function posts a wakeup to a semaphore. If there @@ -249,5 +325,3 @@ sem_post (sem_t * sem) : EINVAL)); } /* sem_post */ - - diff --git a/semaphore.h b/semaphore.h deleted file mode 100644 index 5eeaf3c..0000000 --- a/semaphore.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * ------------------------------------------------------------- - * - * Module: semaphore.h - * - * Purpose: - * Semaphores aren't actually part of the PThreads standard. - * They are defined by the POSIX Standard: - * - * POSIX 1003.1b-1993 (POSIX.1b) - * - * They are supposed to follow the older UNIX convention for - * reporting errors. That is, on failure they are supposed - * to return a value of -1 and store the appropriate error - * number into 'errno'. - * HOWEVER,errno cannot be modified in a multithreaded - * program on WIN32; therefore, the value is returned as - * the function value. - * It is recommended that you compare for zero (0) for success - * instead of -1 for failure when checking the status of - * these functions. - * - * ------------------------------------------------------------- - */ -#if !defined( SEMAPHORE_H ) -#define SEMAPHORE_H - -#include -#include - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - -typedef HANDLE sem_t; - -int sem_init (sem_t * sem, int pshared, unsigned int value); - -int sem_destroy (sem_t * sem); - -int sem_trywait (sem_t * sem); - -int sem_wait (sem_t * sem); - -int sem_post (sem_t * sem); - -#ifdef __cplusplus -} /* End of extern "C" */ -#endif /* __cplusplus */ - -#endif /* !SEMAPHORE_H */ diff --git a/signal.c b/signal.c index ad8a614..9fd222b 100644 --- a/signal.c +++ b/signal.c @@ -12,7 +12,7 @@ #if HAVE_SIGSET_T int -pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) +pthread_sigmask(int how, sigset_t const *set, sigset_t *oset) { pthread_t thread = pthread_self(); @@ -36,18 +36,18 @@ pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) /* Copy the old mask before modifying it. */ if (oset != NULL) { - memcpy(oset, &(thread->attr.sigmask), sizeof(sigset_t)); + memcpy(oset, &(thread->sigmask), sizeof(sigset_t)); } if (set != NULL) { - int i; + unsigned int i; /* FIXME: this code assumes that sigmask is an even multiple of the size of a long integer. */ - unsigned long *src = (long *) set; - unsigned long *dest = &(thread->attr.sigmask); + unsigned long *src = (unsigned long const *) set; + unsigned long *dest = (unsigned long *) &(thread->sigmask); switch (how) { @@ -55,18 +55,18 @@ pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) for (i = 0; i < (sizeof(sigset_t) / sizeof(unsigned long)); i++) { /* OR the bit field longword-wise. */ - *src++ |= *dest++; + *dest++ |= *src++; } break; case SIG_UNBLOCK: for (i = 0; i < (sizeof(sigset_t) / sizeof(unsigned long)); i++) { /* XOR the bitfield longword-wise. */ - *src++ ^= *dest++; + *dest++ ^= *src++; } case SIG_SETMASK: /* Replace the whole sigmask. */ - memcpy(&(thread->attr.sigmask), set, sizeof(sigset_t)); + memcpy(&(thread->sigmask), set, sizeof(sigset_t)); break; } } -- cgit v1.2.3