Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Collins <rbtcollins@hotmail.com>2002-06-10 05:10:45 +0400
committerRobert Collins <rbtcollins@hotmail.com>2002-06-10 05:10:45 +0400
commit007276b30e0a838084eda5c2ac0ba6b9b3243a15 (patch)
tree1e93111058535c8990996c93e17367830e95f2bc
parentfec98ec9938900d7d776a464b6d08704c17e80ff (diff)
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.
-rw-r--r--winsup/cygwin/ChangeLog39
-rw-r--r--winsup/cygwin/cygwin.din2
-rw-r--r--winsup/cygwin/include/pthread.h18
-rw-r--r--winsup/cygwin/pthread.cc16
-rw-r--r--winsup/cygwin/thread.cc76
-rw-r--r--winsup/cygwin/thread.h25
6 files changed, 142 insertions, 34 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 613799b23..417839378 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,44 @@
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>
+
* cygserver_transport.cc (create_server_transport): Finish the split
out of sockets code from transport_layer_base. Thanks to Nicholas
Wourms and Conrad Scott for catching this.
diff --git a/winsup/cygwin/cygwin.din b/winsup/cygwin/cygwin.din
index 9bbfa5f4e..c687f7223 100644
--- a/winsup/cygwin/cygwin.din
+++ b/winsup/cygwin/cygwin.din
@@ -1186,6 +1186,8 @@ pthread_attr_setschedpolicy
pthread_attr_setscope
pthread_attr_setstacksize
pthread_cancel
+_pthread_cleanup_push
+_pthread_cleanup_pop
pthread_cond_broadcast
pthread_cond_destroy
pthread_cond_init
diff --git a/winsup/cygwin/include/pthread.h b/winsup/cygwin/include/pthread.h
index 102ba650c..acdde4fc3 100644
--- a/winsup/cygwin/include/pthread.h
+++ b/winsup/cygwin/include/pthread.h
@@ -103,10 +103,20 @@ void pthread_cleanup_push (void (*routine)(void*), void *arg);
void pthread_cleanup_pop (int execute);
*/
typedef void (*__cleanup_routine_type) (void *);
-
-#define pthread_cleanup_push(fn, arg) { __cleanup_routine_type __cleanup_routine=fn; \
-void *__cleanup_param=arg;
-#define pthread_cleanup_pop(execute) if (execute) __cleanup_routine(__cleanup_param); }
+typedef struct _pthread_cleanup_handler
+{
+ __cleanup_routine_type function;
+ void *arg;
+ struct _pthread_cleanup_handler *next;
+} __pthread_cleanup_handler;
+
+void _pthread_cleanup_push (__pthread_cleanup_handler *handler);
+void _pthread_cleanup_pop (int execute);
+
+#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 */
int pthread_cond_broadcast (pthread_cond_t *);
diff --git a/winsup/cygwin/pthread.cc b/winsup/cygwin/pthread.cc
index 7d8ca1ae6..ab7fd1fbe 100644
--- a/winsup/cygwin/pthread.cc
+++ b/winsup/cygwin/pthread.cc
@@ -218,7 +218,7 @@ pthread_sigmask (int operation, const sigset_t * set, sigset_t * old_set)
pthread_t pthread_self ()
{
- return __pthread_self ();
+ return pthread::self();
}
int
@@ -425,8 +425,6 @@ pthread_cancel (pthread_t thread)
return __pthread_cancel (thread);
}
-
-
int
pthread_setcancelstate (int state, int *oldstate)
{
@@ -445,6 +443,18 @@ pthread_testcancel (void)
__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 */
int
sem_init (sem_t * sem, int pshared, unsigned int value)
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index 5428d674d..dbcfc5a9e 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -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),
-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),
joinable (PTHREAD_CREATE_JOINABLE), contentionscope (PTHREAD_SCOPE_PROCESS),
inheritsched (PTHREAD_INHERIT_SCHED), stacksize (0)
@@ -910,8 +956,8 @@ thread_init_wrapper (void *_arg)
TlsSetValue (MT_INTERFACE->thread_self_dwTlsIndex, thread);
// if thread is detached force cleanup on exit
- if (thread->attr.joinable == PTHREAD_CREATE_DETACHED)
- thread->joiner = __pthread_self();
+ if (thread->attr.joinable == PTHREAD_CREATE_DETACHED && thread->joiner == NULL)
+ thread->joiner = pthread::self ();
#ifdef _CYG_THREAD_FAILSAFE
if (_REENT == _impure_ptr)
@@ -1191,7 +1237,7 @@ opengroup specs.
int
__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)
return EINVAL;
*oldstate = thread->cancelstate;
@@ -1202,7 +1248,7 @@ __pthread_setcancelstate (int state, int *oldstate)
int
__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)
return EINVAL;
*oldtype = thread->canceltype;
@@ -1214,7 +1260,7 @@ __pthread_setcanceltype (int type, int *oldtype)
void
__pthread_testcancel (void)
{
- class pthread *thread = __pthread_self ();
+ class pthread *thread = pthread::self ();
if (thread->cancelstate == PTHREAD_CANCEL_DISABLE)
return;
/*check the cancellation event object here - not neededuntil pthread_cancel actually
@@ -1495,7 +1541,10 @@ __pthread_attr_destroy (pthread_attr_t *attr)
void
__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 ();
@@ -1514,7 +1563,7 @@ __pthread_exit (void *value_ptr)
int
__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*/
if (verifyable_object_isvalid (thread, PTHREAD_MAGIC) != VALID_OBJECT)
@@ -1536,8 +1585,8 @@ __pthread_join (pthread_t *thread, void **return_val)
else
{
- (*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
(*thread)->joiner = joiner;
+ (*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
WaitForSingleObject ((*thread)->win32_obj_id, INFINITE);
if (return_val)
*return_val = (*thread)->return_ptr;
@@ -1561,9 +1610,9 @@ __pthread_detach (pthread_t *thread)
return EINVAL;
}
- (*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
// force cleanup on exit
(*thread)->joiner = *thread;
+ (*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
return 0;
}
@@ -1925,7 +1974,7 @@ __pthread_kill (pthread_t thread, int sig)
int
__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
// two differt kills might clash: FIXME
@@ -1941,11 +1990,6 @@ __pthread_sigmask (int operation, const sigset_t *set, sigset_t *old_set)
}
/* ID */
-pthread_t
-__pthread_self ()
-{
- return (pthread *) TlsGetValue (MT_INTERFACE->thread_self_dwTlsIndex);
-}
int
__pthread_equal (pthread_t *t1, pthread_t *t2)
diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h
index b71c3a31b..25f20b482 100644
--- a/winsup/cygwin/thread.h
+++ b/winsup/cygwin/thread.h
@@ -260,8 +260,17 @@ public:
pthread ();
~pthread ();
+ void push_cleanup_handler (__pthread_cleanup_handler *handler);
+ void pop_cleanup_handler (int const execute);
+
+ static pthread* self ();
+
private:
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
@@ -394,6 +403,11 @@ void __pthread_atforkprepare(void);
void __pthread_atforkparent(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"
{
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_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 */
-
int __pthread_suspend (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);
/* ID */
-pthread_t __pthread_self ();
int __pthread_equal (pthread_t * t1, pthread_t * t2);
-
/* Mutexes */
int __pthread_mutex_init (pthread_mutex_t *, const pthread_mutexattr_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);
void __pthread_testcancel (void);
-
/* Semaphores */
int __sem_init (sem_t * sem, int pshared, unsigned int value);
int __sem_destroy (sem_t * sem);