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:
Diffstat (limited to 'winsup/cygwin/thread.h')
-rw-r--r--winsup/cygwin/thread.h318
1 files changed, 200 insertions, 118 deletions
diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h
index c724bea14..c36466020 100644
--- a/winsup/cygwin/thread.h
+++ b/winsup/cygwin/thread.h
@@ -1,7 +1,6 @@
/* thread.h: Locking and threading module definitions
- Copyright 1998, 1999, 2000, 2001 Red Hat, Inc.
- Copyright 2001 Red Hat, Inc.
+ Copyright 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
Written by Marco Fuykschot <marco@ddi.nl>
Major update 2001 Robert Collins <rbtcollins@hotmail.com>
@@ -54,7 +53,7 @@ struct _winsup_t
/*
Needed for the group functions
*/
- struct group _grp;
+ struct __group16 _grp;
char *_namearray[2];
int _grp_pos;
@@ -164,7 +163,7 @@ public:
~verifyable_object ();
};
-typedef enum
+typedef enum
{
VALID_OBJECT,
INVALID_OBJECT,
@@ -174,51 +173,98 @@ typedef enum
verifyable_object_state verifyable_object_isvalid (void const *, long);
verifyable_object_state verifyable_object_isvalid (void const *, long, void *);
+/* interface */
+template <class ListNode> class List {
+public:
+ List();
+ void Insert (ListNode *aNode);
+ ListNode *Remove ( ListNode *aNode);
+ ListNode *Pop ();
+ void forEach (void (*)(ListNode *aNode));
+protected:
+ ListNode *head;
+};
+
class pthread_key:public verifyable_object
{
public:
+ static bool isGoodObject (pthread_key_t const *);
+ static void runAllDestructors ();
DWORD dwTlsIndex;
+
int set (const void *);
- void *get ();
+ void *get () const;
- pthread_key (void (*)(void *));
+ pthread_key (void (*)(void *));
~pthread_key ();
-};
+ static void fixup_before_fork();
+ static void fixup_after_fork();
-/* FIXME: test using multiple inheritance and merging key_destructor into pthread_key
- * for efficiency */
-class pthread_key_destructor
-{
-public:
+ /* List support calls */
+ class pthread_key *next;
+private:
+ // lists of objects. USE THREADSAFE INSERTS AND DELETES.
+ static List<pthread_key> keys;
+ static void saveAKey (pthread_key *);
+ static void restoreAKey (pthread_key *);
+ static void destroyAKey (pthread_key *);
+ void saveKeyToBuffer ();
+ void recreateKeyFromBuffer ();
void (*destructor) (void *);
- pthread_key_destructor *InsertAfter (pthread_key_destructor * node);
- pthread_key_destructor *UnlinkNext ();
- pthread_key_destructor *Next ();
-
- pthread_key_destructor (void (*thedestructor) (void *), pthread_key * key);
- pthread_key_destructor *next;
- pthread_key *key;
+ void run_destructor () const;
+ void *fork_buf;
};
-class pthread_key_destructor_list
+/* implementation */
+template <class ListNode>
+List<ListNode>::List<ListNode> () : head(NULL)
{
-public:
- void Insert (pthread_key_destructor * node);
-/* remove a given dataitem, wherever in the list it is */
- pthread_key_destructor *Remove (pthread_key_destructor * item);
-/* get the first item and remove at the same time */
- pthread_key_destructor *Pop ();
- pthread_key_destructor *Remove (pthread_key * key);
- void IterateNull ();
-private:
- pthread_key_destructor * head;
-};
-
+}
+template <class ListNode> void
+List<ListNode>::Insert (ListNode *aNode)
+{
+ if (!aNode)
+ return;
+ aNode->next = (ListNode *) InterlockedExchangePointer (&head, aNode);
+}
+template <class ListNode> ListNode *
+List<ListNode>::Remove ( ListNode *aNode)
+{
+ if (!aNode)
+ return NULL;
+ if (!head)
+ return NULL;
+ if (aNode == head)
+ return Pop ();
+ ListNode *resultPrev = head;
+ while (resultPrev && resultPrev->next && !(aNode == resultPrev->next))
+ resultPrev = resultPrev->next;
+ if (resultPrev)
+ return (ListNode *)InterlockedExchangePointer (&resultPrev->next, resultPrev->next->next);
+ return NULL;
+}
+template <class ListNode> ListNode *
+List<ListNode>::Pop ()
+{
+ return (ListNode *) InterlockedExchangePointer (&head, head->next);
+}
+/* poor mans generic programming. */
+template <class ListNode> void
+List<ListNode>::forEach (void (*callback)(ListNode *))
+{
+ ListNode *aNode = head;
+ while (aNode)
+ {
+ callback (aNode);
+ aNode = aNode->next;
+ }
+}
class pthread_attr:public verifyable_object
{
public:
+ static bool isGoodObject(pthread_attr_t const *);
int joinable;
int contentionscope;
int inheritsched;
@@ -229,43 +275,10 @@ public:
~pthread_attr ();
};
-class pthread:public verifyable_object
-{
-public:
- HANDLE win32_obj_id;
- class pthread_attr attr;
- void *(*function) (void *);
- void *arg;
- void *return_ptr;
- bool suspended;
- int cancelstate, canceltype;
- // int joinable;
-
- DWORD GetThreadId ()
- {
- return thread_id;
- }
- void setThreadIdtoCurrent ()
- {
- thread_id = GetCurrentThreadId ();
- }
-
- /* signal handling */
- struct sigaction *sigs;
- sigset_t *sigmask;
- LONG *sigtodo;
- void create (void *(*)(void *), pthread_attr *, void *);
-
- pthread ();
- ~pthread ();
-
-private:
- DWORD thread_id;
-};
-
class pthread_mutexattr:public verifyable_object
{
public:
+ static bool isGoodObject(pthread_mutexattr_t const *);
int pshared;
int mutextype;
pthread_mutexattr ();
@@ -275,6 +288,9 @@ public:
class pthread_mutex:public verifyable_object
{
public:
+ static bool isGoodObject(pthread_mutex_t const *);
+ static bool isGoodInitializer(pthread_mutex_t const *);
+ static bool isGoodInitializerOrObject(pthread_mutex_t const *);
CRITICAL_SECTION criticalsection;
HANDLE win32_obj_id;
LONG condwaits;
@@ -286,15 +302,111 @@ public:
int UnLock ();
void fixup_after_fork ();
- pthread_mutex (unsigned short);
- pthread_mutex (pthread_mutexattr *);
+ pthread_mutex (pthread_mutexattr * = NULL);
pthread_mutex (pthread_mutex_t *, pthread_mutexattr *);
~pthread_mutex ();
};
+class pthread:public verifyable_object
+{
+public:
+ HANDLE win32_obj_id;
+ class pthread_attr attr;
+ void *(*function) (void *);
+ void *arg;
+ void *return_ptr;
+ bool suspended;
+ int cancelstate, canceltype;
+ HANDLE cancel_event;
+ pthread_t joiner;
+ // int joinable;
+
+ /* signal handling */
+ struct sigaction *sigs;
+ sigset_t *sigmask;
+ LONG *sigtodo;
+ virtual void create (void *(*)(void *), pthread_attr *, void *);
+
+ pthread ();
+ virtual ~pthread ();
+
+ static void initMainThread(pthread *, HANDLE);
+ static bool isGoodObject(pthread_t const *);
+ static void atforkprepare();
+ static void atforkparent();
+ static void atforkchild();
+
+ /* API calls */
+ static int cancel (pthread_t);
+ static int join (pthread_t * thread, void **return_val);
+ static int detach (pthread_t * thread);
+ static int create (pthread_t * thread, const pthread_attr_t * attr,
+ void *(*start_routine) (void *), void *arg);
+ static int once (pthread_once_t *, void (*)(void));
+ static int atfork(void (*)(void), void (*)(void), void (*)(void));
+ static int suspend (pthread_t * thread);
+ static int resume (pthread_t * thread);
+
+ virtual void exit (void *value_ptr);
+
+ virtual int cancel ();
+
+ virtual void testcancel ();
+ static void static_cancel_self ();
+
+ virtual int setcancelstate (int state, int *oldstate);
+ virtual int setcanceltype (int type, int *oldtype);
+
+ virtual void push_cleanup_handler (__pthread_cleanup_handler *handler);
+ virtual void pop_cleanup_handler (int const execute);
+
+ static pthread* self ();
+ static void *thread_init_wrapper (void *);
+
+ virtual unsigned long getsequence_np();
+
+private:
+ DWORD thread_id;
+ __pthread_cleanup_handler *cleanup_stack;
+ pthread_mutex mutex;
+
+ void pop_all_cleanup_handlers (void);
+ void precreate (pthread_attr *);
+ void postcreate ();
+ void setThreadIdtoCurrent();
+ static void setTlsSelfPointer(pthread *);
+ void cancel_self ();
+ DWORD getThreadId ();
+};
+
+class pthreadNull : public pthread
+{
+ public:
+ static pthread *getNullpthread();
+ ~pthreadNull();
+
+ /* From pthread These should never get called
+ * as the ojbect is not verifyable
+ */
+ void create (void *(*)(void *), pthread_attr *, void *);
+ void exit (void *value_ptr);
+ int cancel ();
+ void testcancel ();
+ int setcancelstate (int state, int *oldstate);
+ int setcanceltype (int type, int *oldtype);
+ void push_cleanup_handler (__pthread_cleanup_handler *handler);
+ void pop_cleanup_handler (int const execute);
+ unsigned long getsequence_np();
+
+ private:
+ pthreadNull ();
+ static pthreadNull _instance;
+};
+
class pthread_condattr:public verifyable_object
{
public:
+ static bool isGoodObject(pthread_condattr_t const *);
int shared;
pthread_condattr ();
@@ -304,8 +416,12 @@ public:
class pthread_cond:public verifyable_object
{
public:
+ static bool isGoodObject(pthread_cond_t const *);
+ static bool isGoodInitializer(pthread_cond_t const *);
+ static bool isGoodInitializerOrObject(pthread_cond_t const *);
int shared;
LONG waiting;
+ LONG ExitingWait;
pthread_mutex *mutex;
/* to allow atomic behaviour for cond_broadcast */
pthread_mutex_t cond_access;
@@ -331,6 +447,14 @@ public:
class semaphore:public verifyable_object
{
public:
+ static bool isGoodObject(sem_t const *);
+ /* API calls */
+ static int init (sem_t * sem, int pshared, unsigned int value);
+ static int destroy (sem_t * sem);
+ static int wait (sem_t * sem);
+ static int trywait (sem_t * sem);
+ static int post (sem_t * sem);
+
HANDLE win32_obj_id;
class semaphore * next;
int shared;
@@ -367,41 +491,29 @@ public:
struct _winsup_t winsup_reent;
pthread mainthread;
- pthread_key_destructor_list destructors;
callback *pthread_prepare;
callback *pthread_child;
callback *pthread_parent;
- // list of mutex's. USE THREADSAFE INSERTS AND DELETES.
+ // lists of pthread objects. USE THREADSAFE INSERTS AND DELETES.
class pthread_mutex * mutexs;
class pthread_cond * conds;
class semaphore * semaphores;
void Init (int);
+ void fixup_before_fork (void);
void fixup_after_fork (void);
- MTinterface ():reent_index (0), indexallocated (0), threadcount (1)
- {
- pthread_prepare = NULL;
- pthread_child = NULL;
- pthread_parent = NULL;
- }
+ MTinterface ():reent_index (0), indexallocated (0), threadcount (1)
+ {
+ pthread_prepare = NULL;
+ pthread_child = NULL;
+ pthread_parent = NULL;
+ }
};
-void __pthread_atforkprepare(void);
-void __pthread_atforkparent(void);
-void __pthread_atforkchild(void);
-
extern "C"
{
-void *thread_init_wrapper (void *);
-
-/* ThreadCreation */
-int __pthread_create (pthread_t * thread, const pthread_attr_t * attr,
- void *(*start_routine) (void *), void *arg);
-int __pthread_once (pthread_once_t *, void (*)(void));
-int __pthread_atfork(void (*)(void), void (*)(void), void (*)(void));
-
int __pthread_attr_init (pthread_attr_t * attr);
int __pthread_attr_destroy (pthread_attr_t * attr);
int __pthread_attr_setdetachstate (pthread_attr_t *, int);
@@ -422,20 +534,6 @@ 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);
-
-unsigned long __pthread_getsequence_np (pthread_t * thread);
-
/* Thread SpecificData */
int __pthread_key_create (pthread_key_t * key, void (*destructor) (void *));
int __pthread_key_delete (pthread_key_t key);
@@ -460,10 +558,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 *);
@@ -496,21 +592,7 @@ int __pthread_getschedparam (pthread_t thread, int *policy,
int __pthread_setschedparam (pthread_t thread, int policy,
const struct sched_param *param);
-/* cancelability states */
-int __pthread_cancel (pthread_t thread);
-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);
-int __sem_wait (sem_t * sem);
-int __sem_trywait (sem_t * sem);
-int __sem_post (sem_t * sem);
};
-
#endif // MT_SAFE
#endif // _CYGNUS_THREADS_