2002-06-10 Robert Collins <rbtcollins@hotmail.com>
* cygwin.din: Add _pthread_cleanup_push and _pthread_cleanup_pop. * pthread.cc: Change __pthread_self to pthread::self() thruoghout. (_pthread_cleanup_push): New function. (_pthread_cleanup_pop): Ditto. * thread.cc: Thanks to Thomas Pfaff for the pthread cleanup_push,_pop patch, this work is derived from that. Change __pthread_self to pthread::self() thruoghout. (__pthread_self): Rename to pthread::self. (pthread::self): New method. (pthread::pthread): Initialize new member. (pthread::push_cleanup_handler): New method. (pthread::pop_cleanup_handler): New method. (pthread::pop_all_cleanup_handlers): New method. (__pthread_exit): Pop all cleanup handlers. * thread.h (pthread::push_cleanup_handler): Declare. (pthread::pop_cleanup_handler): Ditto. (pthread::pop_all_cleanup_handlers): Ditto. (pthread::self): New static method. (__pthread_exit): Give C++ linkage. (__pthread_join): Ditto. (__pthread_detach): Ditto. (__pthread_self): Remove. 2002-04-24 Thomas Pfaff <tpfaff@gmx.net> * include/pthread.h (__pthread_cleanup_handler): New structure (pthread_cleanup_push): Rewritten . (pthread_cleanup_pop): Ditto. (_pthread_cleanup_push): New prototype. (_pthread_cleanup_pop) Ditto. 2002-04-24 Thomas Pfaff <tpfaff@gmx.net> * thread.cc (thread_init_wrapper): Check if thread is already joined. (__pthread_join): Set joiner first. (__pthread_detach): Ditto.
This commit is contained in:
parent
fec98ec993
commit
007276b30e
|
@ -1,3 +1,42 @@
|
||||||
|
2002-06-10 Robert Collins <rbtcollins@hotmail.com>
|
||||||
|
|
||||||
|
* cygwin.din: Add _pthread_cleanup_push and _pthread_cleanup_pop.
|
||||||
|
* pthread.cc: Change __pthread_self to pthread::self() thruoghout.
|
||||||
|
(_pthread_cleanup_push): New function.
|
||||||
|
(_pthread_cleanup_pop): Ditto.
|
||||||
|
* thread.cc: Thanks to Thomas Pfaff for the pthread cleanup_push,_pop
|
||||||
|
patch, this work is derived from that.
|
||||||
|
Change __pthread_self to pthread::self() thruoghout.
|
||||||
|
(__pthread_self): Rename to pthread::self.
|
||||||
|
(pthread::self): New method.
|
||||||
|
(pthread::pthread): Initialize new member.
|
||||||
|
(pthread::push_cleanup_handler): New method.
|
||||||
|
(pthread::pop_cleanup_handler): New method.
|
||||||
|
(pthread::pop_all_cleanup_handlers): New method.
|
||||||
|
(__pthread_exit): Pop all cleanup handlers.
|
||||||
|
* thread.h (pthread::push_cleanup_handler): Declare.
|
||||||
|
(pthread::pop_cleanup_handler): Ditto.
|
||||||
|
(pthread::pop_all_cleanup_handlers): Ditto.
|
||||||
|
(pthread::self): New static method.
|
||||||
|
(__pthread_exit): Give C++ linkage.
|
||||||
|
(__pthread_join): Ditto.
|
||||||
|
(__pthread_detach): Ditto.
|
||||||
|
(__pthread_self): Remove.
|
||||||
|
|
||||||
|
2002-04-24 Thomas Pfaff <tpfaff@gmx.net>
|
||||||
|
|
||||||
|
* include/pthread.h (__pthread_cleanup_handler): New structure
|
||||||
|
(pthread_cleanup_push): Rewritten .
|
||||||
|
(pthread_cleanup_pop): Ditto.
|
||||||
|
(_pthread_cleanup_push): New prototype.
|
||||||
|
(_pthread_cleanup_pop) Ditto.
|
||||||
|
|
||||||
|
2002-04-24 Thomas Pfaff <tpfaff@gmx.net>
|
||||||
|
|
||||||
|
* thread.cc (thread_init_wrapper): Check if thread is already joined.
|
||||||
|
(__pthread_join): Set joiner first.
|
||||||
|
(__pthread_detach): Ditto.
|
||||||
|
|
||||||
2002-06-10 Robert Collins <rbtcollins@hotmail.com>
|
2002-06-10 Robert Collins <rbtcollins@hotmail.com>
|
||||||
|
|
||||||
* cygserver_transport.cc (create_server_transport): Finish the split
|
* cygserver_transport.cc (create_server_transport): Finish the split
|
||||||
|
|
|
@ -1186,6 +1186,8 @@ pthread_attr_setschedpolicy
|
||||||
pthread_attr_setscope
|
pthread_attr_setscope
|
||||||
pthread_attr_setstacksize
|
pthread_attr_setstacksize
|
||||||
pthread_cancel
|
pthread_cancel
|
||||||
|
_pthread_cleanup_push
|
||||||
|
_pthread_cleanup_pop
|
||||||
pthread_cond_broadcast
|
pthread_cond_broadcast
|
||||||
pthread_cond_destroy
|
pthread_cond_destroy
|
||||||
pthread_cond_init
|
pthread_cond_init
|
||||||
|
|
|
@ -103,10 +103,20 @@ void pthread_cleanup_push (void (*routine)(void*), void *arg);
|
||||||
void pthread_cleanup_pop (int execute);
|
void pthread_cleanup_pop (int execute);
|
||||||
*/
|
*/
|
||||||
typedef void (*__cleanup_routine_type) (void *);
|
typedef void (*__cleanup_routine_type) (void *);
|
||||||
|
typedef struct _pthread_cleanup_handler
|
||||||
|
{
|
||||||
|
__cleanup_routine_type function;
|
||||||
|
void *arg;
|
||||||
|
struct _pthread_cleanup_handler *next;
|
||||||
|
} __pthread_cleanup_handler;
|
||||||
|
|
||||||
#define pthread_cleanup_push(fn, arg) { __cleanup_routine_type __cleanup_routine=fn; \
|
void _pthread_cleanup_push (__pthread_cleanup_handler *handler);
|
||||||
void *__cleanup_param=arg;
|
void _pthread_cleanup_pop (int execute);
|
||||||
#define pthread_cleanup_pop(execute) if (execute) __cleanup_routine(__cleanup_param); }
|
|
||||||
|
#define pthread_cleanup_push(_fn, _arg) { __pthread_cleanup_handler __cleanup_handler = \
|
||||||
|
{ _fn, _arg, NULL }; \
|
||||||
|
_pthread_cleanup_push( &__cleanup_handler );
|
||||||
|
#define pthread_cleanup_pop(_execute) _pthread_cleanup_pop( _execute ); }
|
||||||
|
|
||||||
/* Condition variables */
|
/* Condition variables */
|
||||||
int pthread_cond_broadcast (pthread_cond_t *);
|
int pthread_cond_broadcast (pthread_cond_t *);
|
||||||
|
|
|
@ -218,7 +218,7 @@ pthread_sigmask (int operation, const sigset_t * set, sigset_t * old_set)
|
||||||
|
|
||||||
pthread_t pthread_self ()
|
pthread_t pthread_self ()
|
||||||
{
|
{
|
||||||
return __pthread_self ();
|
return pthread::self();
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -425,8 +425,6 @@ pthread_cancel (pthread_t thread)
|
||||||
return __pthread_cancel (thread);
|
return __pthread_cancel (thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
pthread_setcancelstate (int state, int *oldstate)
|
pthread_setcancelstate (int state, int *oldstate)
|
||||||
{
|
{
|
||||||
|
@ -445,6 +443,18 @@ pthread_testcancel (void)
|
||||||
__pthread_testcancel ();
|
__pthread_testcancel ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_pthread_cleanup_push (__pthread_cleanup_handler *handler)
|
||||||
|
{
|
||||||
|
pthread::self()->push_cleanup_handler(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_pthread_cleanup_pop (int execute)
|
||||||
|
{
|
||||||
|
pthread::self()->pop_cleanup_handler (execute);
|
||||||
|
}
|
||||||
|
|
||||||
/* Semaphores */
|
/* Semaphores */
|
||||||
int
|
int
|
||||||
sem_init (sem_t * sem, int pshared, unsigned int value)
|
sem_init (sem_t * sem, int pshared, unsigned int value)
|
||||||
|
|
|
@ -343,8 +343,19 @@ MTinterface::fixup_after_fork (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* pthread calls */
|
||||||
|
|
||||||
|
/* static methods */
|
||||||
|
|
||||||
|
pthread *
|
||||||
|
pthread::self ()
|
||||||
|
{
|
||||||
|
return (pthread *) TlsGetValue (MT_INTERFACE->thread_self_dwTlsIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* member methods */
|
||||||
pthread::pthread ():verifyable_object (PTHREAD_MAGIC), win32_obj_id (0),
|
pthread::pthread ():verifyable_object (PTHREAD_MAGIC), win32_obj_id (0),
|
||||||
cancelstate (0), canceltype (0), joiner(NULL)
|
cancelstate (0), canceltype (0), joiner (NULL), cleanup_handlers(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,6 +403,41 @@ pthread::create (void *(*func) (void *), pthread_attr *newattr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pthread::push_cleanup_handler (__pthread_cleanup_handler *handler)
|
||||||
|
{
|
||||||
|
if (this != self ())
|
||||||
|
// TODO: do it?
|
||||||
|
api_fatal ("Attempt to push a cleanup handler across threads");
|
||||||
|
handler->next = cleanup_handlers;
|
||||||
|
cleanup_handlers = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pthread::pop_cleanup_handler (int const execute)
|
||||||
|
{
|
||||||
|
if (this != self ())
|
||||||
|
// TODO: send a signal or something to the thread ?
|
||||||
|
api_fatal ("Attempt to execute a cleanup handler across threads");
|
||||||
|
|
||||||
|
if (cleanup_handlers != NULL )
|
||||||
|
{
|
||||||
|
__pthread_cleanup_handler *handler = cleanup_handlers;
|
||||||
|
|
||||||
|
if (execute)
|
||||||
|
(*handler->function) (handler->arg);
|
||||||
|
|
||||||
|
cleanup_handlers = handler->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pthread::pop_all_cleanup_handlers ()
|
||||||
|
{
|
||||||
|
while (cleanup_handlers != NULL)
|
||||||
|
pop_cleanup_handler (1);
|
||||||
|
}
|
||||||
|
|
||||||
pthread_attr::pthread_attr ():verifyable_object (PTHREAD_ATTR_MAGIC),
|
pthread_attr::pthread_attr ():verifyable_object (PTHREAD_ATTR_MAGIC),
|
||||||
joinable (PTHREAD_CREATE_JOINABLE), contentionscope (PTHREAD_SCOPE_PROCESS),
|
joinable (PTHREAD_CREATE_JOINABLE), contentionscope (PTHREAD_SCOPE_PROCESS),
|
||||||
inheritsched (PTHREAD_INHERIT_SCHED), stacksize (0)
|
inheritsched (PTHREAD_INHERIT_SCHED), stacksize (0)
|
||||||
|
@ -910,8 +956,8 @@ thread_init_wrapper (void *_arg)
|
||||||
TlsSetValue (MT_INTERFACE->thread_self_dwTlsIndex, thread);
|
TlsSetValue (MT_INTERFACE->thread_self_dwTlsIndex, thread);
|
||||||
|
|
||||||
// if thread is detached force cleanup on exit
|
// if thread is detached force cleanup on exit
|
||||||
if (thread->attr.joinable == PTHREAD_CREATE_DETACHED)
|
if (thread->attr.joinable == PTHREAD_CREATE_DETACHED && thread->joiner == NULL)
|
||||||
thread->joiner = __pthread_self();
|
thread->joiner = pthread::self ();
|
||||||
|
|
||||||
#ifdef _CYG_THREAD_FAILSAFE
|
#ifdef _CYG_THREAD_FAILSAFE
|
||||||
if (_REENT == _impure_ptr)
|
if (_REENT == _impure_ptr)
|
||||||
|
@ -1191,7 +1237,7 @@ opengroup specs.
|
||||||
int
|
int
|
||||||
__pthread_setcancelstate (int state, int *oldstate)
|
__pthread_setcancelstate (int state, int *oldstate)
|
||||||
{
|
{
|
||||||
class pthread *thread = __pthread_self ();
|
class pthread *thread = pthread::self ();
|
||||||
if (state != PTHREAD_CANCEL_ENABLE && state != PTHREAD_CANCEL_DISABLE)
|
if (state != PTHREAD_CANCEL_ENABLE && state != PTHREAD_CANCEL_DISABLE)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
*oldstate = thread->cancelstate;
|
*oldstate = thread->cancelstate;
|
||||||
|
@ -1202,7 +1248,7 @@ __pthread_setcancelstate (int state, int *oldstate)
|
||||||
int
|
int
|
||||||
__pthread_setcanceltype (int type, int *oldtype)
|
__pthread_setcanceltype (int type, int *oldtype)
|
||||||
{
|
{
|
||||||
class pthread *thread = __pthread_self ();
|
class pthread *thread = pthread::self ();
|
||||||
if (type != PTHREAD_CANCEL_DEFERRED && type != PTHREAD_CANCEL_ASYNCHRONOUS)
|
if (type != PTHREAD_CANCEL_DEFERRED && type != PTHREAD_CANCEL_ASYNCHRONOUS)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
*oldtype = thread->canceltype;
|
*oldtype = thread->canceltype;
|
||||||
|
@ -1214,7 +1260,7 @@ __pthread_setcanceltype (int type, int *oldtype)
|
||||||
void
|
void
|
||||||
__pthread_testcancel (void)
|
__pthread_testcancel (void)
|
||||||
{
|
{
|
||||||
class pthread *thread = __pthread_self ();
|
class pthread *thread = pthread::self ();
|
||||||
if (thread->cancelstate == PTHREAD_CANCEL_DISABLE)
|
if (thread->cancelstate == PTHREAD_CANCEL_DISABLE)
|
||||||
return;
|
return;
|
||||||
/*check the cancellation event object here - not neededuntil pthread_cancel actually
|
/*check the cancellation event object here - not neededuntil pthread_cancel actually
|
||||||
|
@ -1495,7 +1541,10 @@ __pthread_attr_destroy (pthread_attr_t *attr)
|
||||||
void
|
void
|
||||||
__pthread_exit (void *value_ptr)
|
__pthread_exit (void *value_ptr)
|
||||||
{
|
{
|
||||||
pthread_t thread = __pthread_self ();
|
pthread * thread = pthread::self ();
|
||||||
|
|
||||||
|
// run cleanup handlers
|
||||||
|
thread->pop_all_cleanup_handlers();
|
||||||
|
|
||||||
MT_INTERFACE->destructors.IterateNull ();
|
MT_INTERFACE->destructors.IterateNull ();
|
||||||
|
|
||||||
|
@ -1514,7 +1563,7 @@ __pthread_exit (void *value_ptr)
|
||||||
int
|
int
|
||||||
__pthread_join (pthread_t *thread, void **return_val)
|
__pthread_join (pthread_t *thread, void **return_val)
|
||||||
{
|
{
|
||||||
pthread_t joiner = __pthread_self();
|
pthread_t joiner = pthread::self ();
|
||||||
|
|
||||||
/*FIXME: wait on the thread cancellation event as well - we are a cancellation point*/
|
/*FIXME: wait on the thread cancellation event as well - we are a cancellation point*/
|
||||||
if (verifyable_object_isvalid (thread, PTHREAD_MAGIC) != VALID_OBJECT)
|
if (verifyable_object_isvalid (thread, PTHREAD_MAGIC) != VALID_OBJECT)
|
||||||
|
@ -1536,8 +1585,8 @@ __pthread_join (pthread_t *thread, void **return_val)
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
(*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
|
|
||||||
(*thread)->joiner = joiner;
|
(*thread)->joiner = joiner;
|
||||||
|
(*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
|
||||||
WaitForSingleObject ((*thread)->win32_obj_id, INFINITE);
|
WaitForSingleObject ((*thread)->win32_obj_id, INFINITE);
|
||||||
if (return_val)
|
if (return_val)
|
||||||
*return_val = (*thread)->return_ptr;
|
*return_val = (*thread)->return_ptr;
|
||||||
|
@ -1561,9 +1610,9 @@ __pthread_detach (pthread_t *thread)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
|
|
||||||
// force cleanup on exit
|
// force cleanup on exit
|
||||||
(*thread)->joiner = *thread;
|
(*thread)->joiner = *thread;
|
||||||
|
(*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1925,7 +1974,7 @@ __pthread_kill (pthread_t thread, int sig)
|
||||||
int
|
int
|
||||||
__pthread_sigmask (int operation, const sigset_t *set, sigset_t *old_set)
|
__pthread_sigmask (int operation, const sigset_t *set, sigset_t *old_set)
|
||||||
{
|
{
|
||||||
pthread *thread = __pthread_self ();
|
pthread *thread = pthread::self ();
|
||||||
|
|
||||||
// lock this myself, for the use of thread2signal
|
// lock this myself, for the use of thread2signal
|
||||||
// two differt kills might clash: FIXME
|
// two differt kills might clash: FIXME
|
||||||
|
@ -1941,11 +1990,6 @@ __pthread_sigmask (int operation, const sigset_t *set, sigset_t *old_set)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ID */
|
/* ID */
|
||||||
pthread_t
|
|
||||||
__pthread_self ()
|
|
||||||
{
|
|
||||||
return (pthread *) TlsGetValue (MT_INTERFACE->thread_self_dwTlsIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
__pthread_equal (pthread_t *t1, pthread_t *t2)
|
__pthread_equal (pthread_t *t1, pthread_t *t2)
|
||||||
|
|
|
@ -260,8 +260,17 @@ public:
|
||||||
pthread ();
|
pthread ();
|
||||||
~pthread ();
|
~pthread ();
|
||||||
|
|
||||||
|
void push_cleanup_handler (__pthread_cleanup_handler *handler);
|
||||||
|
void pop_cleanup_handler (int const execute);
|
||||||
|
|
||||||
|
static pthread* self ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DWORD thread_id;
|
DWORD thread_id;
|
||||||
|
__pthread_cleanup_handler *cleanup_handlers;
|
||||||
|
|
||||||
|
friend void __pthread_exit (void *value_ptr);
|
||||||
|
void pop_all_cleanup_handlers (void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class pthread_mutexattr:public verifyable_object
|
class pthread_mutexattr:public verifyable_object
|
||||||
|
@ -394,6 +403,11 @@ void __pthread_atforkprepare(void);
|
||||||
void __pthread_atforkparent(void);
|
void __pthread_atforkparent(void);
|
||||||
void __pthread_atforkchild(void);
|
void __pthread_atforkchild(void);
|
||||||
|
|
||||||
|
/* Thread Exit */
|
||||||
|
void __pthread_exit (void *value_ptr);
|
||||||
|
int __pthread_join (pthread_t * thread, void **return_val);
|
||||||
|
int __pthread_detach (pthread_t * thread);
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
void *thread_init_wrapper (void *);
|
void *thread_init_wrapper (void *);
|
||||||
|
@ -424,15 +438,7 @@ int __pthread_attr_setschedpolicy (pthread_attr_t *, int);
|
||||||
int __pthread_attr_setscope (pthread_attr_t *, int);
|
int __pthread_attr_setscope (pthread_attr_t *, int);
|
||||||
int __pthread_attr_setstackaddr (pthread_attr_t *, void *);
|
int __pthread_attr_setstackaddr (pthread_attr_t *, void *);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Thread Exit */
|
|
||||||
void __pthread_exit (void *value_ptr);
|
|
||||||
int __pthread_join (pthread_t * thread, void **return_val);
|
|
||||||
int __pthread_detach (pthread_t * thread);
|
|
||||||
|
|
||||||
/* Thread suspend */
|
/* Thread suspend */
|
||||||
|
|
||||||
int __pthread_suspend (pthread_t * thread);
|
int __pthread_suspend (pthread_t * thread);
|
||||||
int __pthread_continue (pthread_t * thread);
|
int __pthread_continue (pthread_t * thread);
|
||||||
|
|
||||||
|
@ -462,10 +468,8 @@ int __pthread_sigmask (int operation, const sigset_t * set,
|
||||||
sigset_t * old_set);
|
sigset_t * old_set);
|
||||||
|
|
||||||
/* ID */
|
/* ID */
|
||||||
pthread_t __pthread_self ();
|
|
||||||
int __pthread_equal (pthread_t * t1, pthread_t * t2);
|
int __pthread_equal (pthread_t * t1, pthread_t * t2);
|
||||||
|
|
||||||
|
|
||||||
/* Mutexes */
|
/* Mutexes */
|
||||||
int __pthread_mutex_init (pthread_mutex_t *, const pthread_mutexattr_t *);
|
int __pthread_mutex_init (pthread_mutex_t *, const pthread_mutexattr_t *);
|
||||||
int __pthread_mutex_lock (pthread_mutex_t *);
|
int __pthread_mutex_lock (pthread_mutex_t *);
|
||||||
|
@ -504,7 +508,6 @@ int __pthread_setcancelstate (int state, int *oldstate);
|
||||||
int __pthread_setcanceltype (int type, int *oldtype);
|
int __pthread_setcanceltype (int type, int *oldtype);
|
||||||
void __pthread_testcancel (void);
|
void __pthread_testcancel (void);
|
||||||
|
|
||||||
|
|
||||||
/* Semaphores */
|
/* Semaphores */
|
||||||
int __sem_init (sem_t * sem, int pshared, unsigned int value);
|
int __sem_init (sem_t * sem, int pshared, unsigned int value);
|
||||||
int __sem_destroy (sem_t * sem);
|
int __sem_destroy (sem_t * sem);
|
||||||
|
|
Loading…
Reference in New Issue