diff options
-rw-r--r-- | ChangeLog | 26 | ||||
-rw-r--r-- | PROGRESS | 6 | ||||
-rw-r--r-- | attr.c | 30 | ||||
-rw-r--r-- | implement.h | 34 | ||||
-rw-r--r-- | private.c | 10 | ||||
-rw-r--r-- | pthread.h | 54 | ||||
-rw-r--r-- | sync.c | 42 |
7 files changed, 127 insertions, 75 deletions
@@ -1,3 +1,29 @@ +Fri Jul 24 03:00:25 1998 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * attr.c (pthread_attr_destroy): Fix merge conflicts. + (pthread_attr_getdetachstate): Fix merge conflicts. + (pthread_attr_setdetachstate): Fix merge conflicts. + + * pthread.h: Fix merge conflicts. + + * sync.c (pthread_join): Fix merge conflicts. + +Fri Jul 24 00:21:21 1998 Ross Johnson <rpj@ixobrychus.canberra.edu.au> + + * sync.c (pthread_join): Add check for valid and joinable + thread. + (pthread_detach): Implement. After checking for a valid and joinable + thread, it's still a no-op. + + * private.c (_pthread_find_thread_entry): Bug prevented returning + an error value in some cases. + + * attr.c (pthread_attr_setdetachedstate): Implement. + (pthread_attr_getdetachedstate): Implement. + + * implement.h: Move more hidden definitions into here from + pthread.h. + 1998-07-24 Ben Elliston <bje@cygnus.com> * pthread.h (PTHREAD_CREATE_JOINABLE): Define. @@ -1,4 +1,4 @@ -Last updated: $Date: 1998/07/23 16:00:12 $ +Last updated: $Date: 1998/07/23 17:12:12 $ Completion: 54 out of 61 functions [ 88%] @@ -38,7 +38,7 @@ no. name status 29 pthread_cond_timedwait * 30 pthread_cond_wait * 31 pthread_create * -32 pthread_detach +32 pthread_detach * 33 pthread_equal * 34 pthread_exit * 35 pthread_getschedparam * @@ -66,5 +66,5 @@ no. name status 57 pthread_setcanceltype * 58 pthread_setschedparam * 59 pthread_setspecific * -60 pthread_sigmask +60 pthread_sigmask 61 pthread_testcancel @@ -11,7 +11,7 @@ static int is_attr(pthread_attr_t *attr) { - /* Return 0 if the attr object is valid, 1 otherwise. */ + /* Return 0 if the attr object is valid, non-zero otherwise. */ return (attr == NULL || attr->valid != _PTHREAD_ATTR_VALID); } @@ -107,6 +107,20 @@ pthread_attr_init(pthread_attr_t *attr) } int +pthread_attr_destroy(pthread_attr_t *attr) +{ + if (is_attr(attr) != 0) + { + return EINVAL; + } + + /* Set the attribute object to a specific invalid value. */ + attr->valid = _PTHREAD_ATTR_INVALID; + + return 0; +} + +int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate) { @@ -137,17 +151,3 @@ pthread_attr_setdetachstate(pthread_attr_t *attr, attr->detached = detachstate; return 0; } - -int -pthread_attr_destroy(pthread_attr_t *attr) -{ - if (is_attr(attr) != 0) - { - return EINVAL; - } - - /* Set the attribute object to a specific invalid value. */ - attr->valid = _PTHREAD_ATTR_INVALID; - - return 0; -} diff --git a/implement.h b/implement.h index ea68d2f..14fbdbb 100644 --- a/implement.h +++ b/implement.h @@ -51,13 +51,6 @@ struct _pthread_threads_thread { pthread_t thread; pthread_attr_t attr; _pthread_call_t call; - enum { - _PTHREAD_CLEANUP_STACK, - _PTHREAD_DESTRUCTOR_STACK, - _PTHREAD_FORKPREPARE_STACK, - _PTHREAD_FORKPARENT_STACK, - _PTHREAD_FORKCHILD_STACK - }; _pthread_handler_node_t * cleanupstack; _pthread_handler_node_t * destructorstack; _pthread_handler_node_t * forkpreparestack; @@ -69,6 +62,19 @@ struct _pthread_threads_thread { extern "C" { #endif /* __cplusplus */ +/* Generic handler push and pop routines. */ + +void _pthread_handler_push(_pthread_handler_node_t ** stacktop, + int poporder, + void (*routine)(void *), + void *arg); + +void _pthread_handler_pop(_pthread_handler_node_t ** stacktop, + int execute); + +void _pthread_handler_pop_all(_pthread_handler_node_t ** stacktop, + int execute); + /* Primitives to manage threads table entries. */ int _pthread_new_thread_entry(pthread_t thread, @@ -87,6 +93,18 @@ void _pthread_vacuum(void); #endif /* __cplusplus */ -#endif /* _IMPLEMENT_H */ +/* Global data declared in global.c */ + +extern pthread_mutex_t _pthread_count_mutex; +extern DWORD _pthread_threads_count; + +extern _pthread_threads_thread_t _pthread_threads_table[]; + +extern unsigned short _pthread_once_flag; + +extern pthread_mutex_t _pthread_once_lock; + + +#endif /* _IMPLEMENT_H */ @@ -92,12 +92,12 @@ _pthread_find_thread_entry(pthread_t thread) /* Wrap to top of table. */ this = _pthread_threads_table; } + } - if (this->thread == NULL || this == start) - { - /* Failed to find the thread. */ - return -1; - } + if (this->thread == NULL || this == start) + { + /* Failed to find the thread. */ + return -1; } return this; @@ -58,19 +58,22 @@ typedef DWORD pthread_key_t; /* Related constants */ typedef struct { long valid; + #ifdef _POSIX_THREAD_ATTR_STACKSIZE size_t stacksize; /* PTHREAD_STACK_MIN */ #endif + int cancelability; /* PTHREAD_CANCEL_DISABLE PTHREAD_CANCEL_ENABLE */ + int detached; /* PTHREAD_CREATE_DETACHED + PTHREAD_CREATE_JOINABLE */ + int canceltype; /* PTHREAD_CANCEL_ASYNCHRONOUS PTHREAD_CANCEL_DEFERRED */ - int detached; /* PTHREAD_CREATE_JOINABLE - PTHREAD_CREATE_DETACHED */ - int priority; + } pthread_attr_t; /* I don't know why this structure isn't in some kind of namespace. @@ -122,6 +125,8 @@ int pthread_equal(pthread_t t1, pthread_t t2); int pthread_join(pthread_t thread, void ** valueptr); +int pthread_detach(pthread_t thread); + int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)); /* Functions for manipulating thread attribute objects. */ @@ -238,22 +243,6 @@ void *pthread_getspecific(pthread_key_t key); int pthread_key_delete(pthread_key_t key); - -/* Internal primitives that must be here. */ - -/* Generic handler push and pop routines. */ - -void _pthread_handler_push(_pthread_handler_node_t ** stacktop, - int poporder, - void (*routine)(void *), - void *arg); - -void _pthread_handler_pop(_pthread_handler_node_t ** stacktop, - int execute); - -void _pthread_handler_pop_all(_pthread_handler_node_t ** stacktop, - int execute); - #ifdef __cplusplus } #endif /* __cplusplus */ @@ -266,13 +255,21 @@ void _pthread_handler_pop_all(_pthread_handler_node_t ** stacktop, POSIX requires that applications observe scoping requirements, but doesn't say if the implemention must enforce them. The macros below - partially enforce scope but can lead to compile or runtime errors. - */ + partially enforce scope but can lead to compile or runtime errors. */ + enum { _PTHREAD_HANDLER_POP_LIFO, _PTHREAD_HANDLER_POP_FIFO }; +enum { + _PTHREAD_CLEANUP_STACK, + _PTHREAD_DESTRUCTOR_STACK, + _PTHREAD_FORKPREPARE_STACK, + _PTHREAD_FORKPARENT_STACK, + _PTHREAD_FORKCHILD_STACK +}; + #ifdef pthread_cleanup_push #undef pthread_cleanup_push #endif @@ -290,19 +287,4 @@ enum { _pthread_handler_pop(_PTHREAD_CLEANUP_STACK, execute);\ } - -/* Global data needed by the application but which must not be static - in the DLL. */ - -extern pthread_mutex_t _pthread_count_mutex; - -extern DWORD _pthread_threads_count; - -extern _pthread_threads_thread_t _pthread_threads_table[]; - -extern unsigned short _pthread_once_flag; - -extern pthread_mutex_t _pthread_once_lock; - - #endif /* _PTHREADS_H */ @@ -12,8 +12,7 @@ int pthread_join(pthread_t thread, void ** valueptr) { LPDWORD exitcode; - _pthread_threads_thread_t * target; - + int detachstate; pthread_t us = pthread_self(); /* First check if we are trying to join to ourselves. */ @@ -22,16 +21,20 @@ pthread_join(pthread_t thread, void ** valueptr) return EDEADLK; } - /* If the thread is detached, then join will return immediately. */ + /* Find the thread. */ + this = _pthread_find_thread_entry(thread); - target = _pthread_find_thread_entry(thread); - if (target < 0) + if (this == -1) { - return EINVAL; + return ESRCH; } - else if (target->detached == PTHREAD_CREATE_DETACHED) + + /* If the thread is detached, then join will return immediately. */ + + if (pthread_attr_getdetachedstate(&(this->attr), &detachstate) != 0 + || detachstate == PTHREAD_CREATE_DETACHED) { - return ESRCH; + return EINVAL; } /* Wait on the kernel thread object. */ @@ -60,3 +63,26 @@ pthread_join(pthread_t thread, void ** valueptr) return &exitcode; } +int +pthread_detach(pthread_t thread) +{ + _pthread_threads_thread_t * this; + int detachstate; + + this = _pthread_find_thread_entry(thread); + + if (this = -1) + { + return ESRCH; + } + + /* Check that we can detach this thread. */ + if (pthread_attr_getdetachedstate(&(this->attr), &detachstate) != 0 + || detachstate == PTHREAD_CREATE_DETACHED) + { + return EINVAL; + } + + /* FIXME: As far as I can determine we just no-op. */ + return 0; +} |