OSDN Git Service

ed79b8debc041fb08751cead075efc123e0af756
[pf3gnuchains/sourceware.git] / winsup / cygwin / thread.h
1 /* thread.h: Locking and threading module definitions
2
3    Copyright 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
4
5    Written by Marco Fuykschot <marco@ddi.nl>
6    Major update 2001 Robert Collins <rbtcollins@hotmail.com>
7
8 This file is part of Cygwin.
9
10 This software is a copyrighted work licensed under the terms of the
11 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
12 details. */
13
14 #ifndef _CYGNUS_THREADS_
15 #define _CYGNUS_THREADS_
16
17 #define LOCK_FD_LIST     1
18 #define LOCK_MEMORY_LIST 2
19 #define LOCK_MMAP_LIST   3
20 #define LOCK_DLL_LIST    4
21
22 #define WRITE_LOCK 1
23 #define READ_LOCK  2
24
25 #include <pthread.h>
26 #include <limits.h>
27 #include <security.h>
28 #include <errno.h>
29
30 extern "C"
31 {
32 void SetResourceLock (int, int, const char *) __attribute__ ((regparm (3)));
33 void ReleaseResourceLock (int, int, const char *)
34   __attribute__ ((regparm (3)));
35 }
36
37 class fast_mutex
38 {
39 public:
40   fast_mutex () :
41     lock_counter (0), win32_obj_id (0)
42   {
43   }
44
45   ~fast_mutex ()
46   {
47     if(win32_obj_id)
48       CloseHandle (win32_obj_id);
49   }
50
51   bool init ()
52   {
53     lock_counter = 0;
54     win32_obj_id = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL);
55     if (!win32_obj_id)
56       {
57         debug_printf ("CreateSemaphore failed. %E");
58         return false;
59       }
60     return true;
61   }
62
63   void lock ()
64   {
65     if (InterlockedIncrement ((long *)&lock_counter) != 1)
66       WaitForSingleObject (win32_obj_id, INFINITE);
67   }
68
69   void unlock ()
70   {
71     if (InterlockedDecrement ((long *)&lock_counter))
72       ::ReleaseSemaphore (win32_obj_id, 1, NULL);
73   }
74
75 private:
76   unsigned long lock_counter;
77   HANDLE win32_obj_id;
78 };
79
80 class per_process;
81 class pinfo;
82
83 class ResourceLocks
84 {
85 public:
86   LPCRITICAL_SECTION Lock (int);
87   void Init ();
88   void Delete ();
89 private:
90   CRITICAL_SECTION lock;
91   bool inited;
92 };
93
94 #define PTHREAD_MAGIC 0xdf0df045
95 #define PTHREAD_MUTEX_MAGIC PTHREAD_MAGIC+1
96 #define PTHREAD_KEY_MAGIC PTHREAD_MAGIC+2
97 #define PTHREAD_ATTR_MAGIC PTHREAD_MAGIC+3
98 #define PTHREAD_MUTEXATTR_MAGIC PTHREAD_MAGIC+4
99 #define PTHREAD_COND_MAGIC PTHREAD_MAGIC+5
100 #define PTHREAD_CONDATTR_MAGIC PTHREAD_MAGIC+6
101 #define SEM_MAGIC PTHREAD_MAGIC+7
102 #define PTHREAD_ONCE_MAGIC PTHREAD_MAGIC+8
103 #define PTHREAD_RWLOCK_MAGIC PTHREAD_MAGIC+9
104 #define PTHREAD_RWLOCKATTR_MAGIC PTHREAD_MAGIC+10
105
106 #define MUTEX_OWNER_ANONYMOUS        ((pthread_t) -1)
107
108 /* verifyable_object should not be defined here - it's a general purpose class */
109
110 class verifyable_object
111 {
112 public:
113   long magic;
114
115   verifyable_object (long);
116   virtual ~verifyable_object ();
117 };
118
119 typedef enum
120 {
121   VALID_OBJECT,
122   INVALID_OBJECT,
123   VALID_STATIC_OBJECT
124 } verifyable_object_state;
125
126 verifyable_object_state verifyable_object_isvalid (void const *, long);
127 verifyable_object_state verifyable_object_isvalid (void const *, long, void *);
128
129 template <class list_node> inline void
130 List_insert (list_node *&head, list_node *node)
131 {
132   if (!node)
133     return;
134   do
135     node->next = head;
136   while (InterlockedCompareExchangePointer (&head, node, node->next) != node->next);
137 }
138
139 template <class list_node> inline void
140 List_remove (fast_mutex &mx, list_node *&head, list_node *node)
141 {
142   if (!node)
143     return;
144   mx.lock ();
145   if (head)
146     {
147       if (InterlockedCompareExchangePointer (&head, node->next, node) != node)
148         {
149           list_node *cur = head;
150
151           while (cur->next && node != cur->next)
152             cur = cur->next;
153           if (node == cur->next)
154             cur->next = cur->next->next;
155         }
156     }
157   mx.unlock ();
158 }
159
160
161 template <class list_node> class List
162 {
163  public:
164   List() : head(NULL)
165   {
166     mx_init ();
167   }
168
169   ~List()
170   {
171   }
172
173   void fixup_after_fork ()
174   {
175     mx_init ();
176   }
177
178   void insert (list_node *node)
179   {
180     List_insert (head, node);
181   }
182
183   void remove (list_node *node)
184   {
185     List_remove (mx, head, node);
186   }
187
188   void for_each (void (list_node::*callback) ())
189   {
190     mx.lock ();
191     list_node *cur = head;
192     while (cur)
193       {
194         (cur->*callback) ();
195         cur = cur->next;
196       }
197     mx.unlock ();
198   }
199
200 protected:
201   void mx_init ()
202   {
203     if (!mx.init ())
204       api_fatal ("Could not create mutex for list synchronisation.");
205   }
206
207   fast_mutex mx;
208   list_node *head;
209 };
210
211 class pthread_key: public verifyable_object
212 {
213 public:
214   static bool is_good_object (pthread_key_t const *);
215   DWORD tls_index;
216
217   int set (const void *);
218   void *get () const;
219
220   pthread_key (void (*)(void *));
221   ~pthread_key ();
222   static void fixup_before_fork ()
223   {
224     keys.for_each (&pthread_key::_fixup_before_fork);
225   }
226
227   static void fixup_after_fork ()
228   {
229     keys.fixup_after_fork ();
230     keys.for_each (&pthread_key::_fixup_after_fork);
231   }
232
233   static void run_all_destructors ()
234   {
235     keys.for_each (&pthread_key::run_destructor);
236   }
237
238   /* List support calls */
239   class pthread_key *next;
240 private:
241   static List<pthread_key> keys;
242   void _fixup_before_fork ();
243   void _fixup_after_fork ();
244   void (*destructor) (void *);
245   void run_destructor ();
246   void *fork_buf;
247 };
248
249 class pthread_attr: public verifyable_object
250 {
251 public:
252   static bool is_good_object(pthread_attr_t const *);
253   int joinable;
254   int contentionscope;
255   int inheritsched;
256   struct sched_param schedparam;
257   size_t stacksize;
258
259   pthread_attr ();
260   ~pthread_attr ();
261 };
262
263 class pthread_mutexattr: public verifyable_object
264 {
265 public:
266   static bool is_good_object(pthread_mutexattr_t const *);
267   int pshared;
268   int mutextype;
269   pthread_mutexattr ();
270   ~pthread_mutexattr ();
271 };
272
273 class pthread_mutex: public verifyable_object
274 {
275 public:
276   static bool is_good_object (pthread_mutex_t const *);
277   static bool is_good_initializer (pthread_mutex_t const *);
278   static bool is_good_initializer_or_object (pthread_mutex_t const *);
279   static bool is_good_initializer_or_bad_object (pthread_mutex_t const *mutex);
280   static bool can_be_unlocked (pthread_mutex_t const *mutex);
281   static void init_mutex ();
282   static int init (pthread_mutex_t *, const pthread_mutexattr_t *);
283
284   unsigned long lock_counter;
285   HANDLE win32_obj_id;
286   unsigned int recursion_counter;
287   LONG condwaits;
288   pthread_t owner;
289   int type;
290   int pshared;
291
292   pthread_t get_pthread_self () const
293   {
294     return PTHREAD_MUTEX_NORMAL == type ? MUTEX_OWNER_ANONYMOUS :
295       ::pthread_self ();
296   }
297
298   int lock ()
299   {
300     return _lock (get_pthread_self ());
301   }
302   int trylock ()
303   {
304     return _trylock (get_pthread_self ());
305   }
306   int unlock ()
307   {
308     return _unlock (get_pthread_self ());
309   }
310   int destroy ()
311   {
312     return _destroy (get_pthread_self ());
313   }
314
315   void set_owner (pthread_t self)
316   {
317     recursion_counter = 1;
318     owner = self;
319   }
320
321   int lock_recursive ()
322   {
323     if (UINT_MAX == recursion_counter)
324       return EAGAIN;
325     ++recursion_counter;
326     return 0;
327   }
328
329   pthread_mutex (pthread_mutexattr * = NULL);
330   pthread_mutex (pthread_mutex_t *, pthread_mutexattr *);
331   ~pthread_mutex ();
332
333   class pthread_mutex * next;
334   static void fixup_after_fork ()
335   {
336     mutexes.fixup_after_fork ();
337     mutexes.for_each (&pthread_mutex::_fixup_after_fork);
338   }
339
340 private:
341   int _lock (pthread_t self);
342   int _trylock (pthread_t self);
343   int _unlock (pthread_t self);
344   int _destroy (pthread_t self);
345
346   void _fixup_after_fork ();
347
348   static List<pthread_mutex> mutexes;
349   static fast_mutex mutex_initialization_lock;
350 };
351
352 #define WAIT_CANCELED   (WAIT_OBJECT_0 + 1)
353
354 class _threadinfo;
355 class pthread: public verifyable_object
356 {
357 public:
358   HANDLE win32_obj_id;
359   class pthread_attr attr;
360   void *(*function) (void *);
361   void *arg;
362   void *return_ptr;
363   bool valid;
364   bool suspended;
365   int cancelstate, canceltype;
366   _threadinfo *cygtls;
367   HANDLE cancel_event;
368   pthread_t joiner;
369
370   virtual void create (void *(*)(void *), pthread_attr *, void *);
371
372   pthread ();
373   virtual ~pthread ();
374
375   static void init_mainthread ();
376   static bool is_good_object(pthread_t const *);
377   static void atforkprepare();
378   static void atforkparent();
379   static void atforkchild();
380
381   /* API calls */
382   static int cancel (pthread_t);
383   static int join (pthread_t * thread, void **return_val);
384   static int detach (pthread_t * thread);
385   static int create (pthread_t * thread, const pthread_attr_t * attr,
386                               void *(*start_routine) (void *), void *arg);
387   static int once (pthread_once_t *, void (*)(void));
388   static int atfork(void (*)(void), void (*)(void), void (*)(void));
389   static int suspend (pthread_t * thread);
390   static int resume (pthread_t * thread);
391
392   virtual void exit (void *value_ptr) __attribute__ ((noreturn));
393
394   virtual int cancel ();
395
396   virtual void testcancel ();
397   static void static_cancel_self ();
398
399   static DWORD cancelable_wait (HANDLE object, DWORD timeout, const bool do_cancel = true);
400
401   virtual int setcancelstate (int state, int *oldstate);
402   virtual int setcanceltype (int type, int *oldtype);
403
404   virtual void push_cleanup_handler (__pthread_cleanup_handler *handler);
405   virtual void pop_cleanup_handler (int const execute);
406
407   static pthread* self ();
408   static DWORD WINAPI thread_init_wrapper (void *);
409
410   virtual unsigned long getsequence_np();
411
412   static int equal (pthread_t t1, pthread_t t2)
413   {
414     return t1 == t2;
415   }
416
417   /* List support calls */
418   class pthread *next;
419   static void fixup_after_fork ()
420   {
421     threads.fixup_after_fork ();
422     threads.for_each (&pthread::_fixup_after_fork);
423   }
424
425   static void suspend_all_except_self ()
426   {
427     threads.for_each (&pthread::suspend_except_self);
428   }
429
430   static void resume_all ()
431   {
432     threads.for_each (&pthread::resume);
433   }
434
435 private:
436   static List<pthread> threads;
437   DWORD thread_id;
438   __pthread_cleanup_handler *cleanup_stack;
439   pthread_mutex mutex;
440
441   void suspend_except_self ();
442   void resume ();
443
444   void _fixup_after_fork ();
445
446   void pop_all_cleanup_handlers (void);
447   void precreate (pthread_attr *);
448   void postcreate ();
449   void set_tls_self_pointer ();
450   bool create_cancel_event ();
451   static pthread *get_tls_self_pointer ();
452   void cancel_self ();
453   DWORD get_thread_id ();
454 };
455
456 class pthread_null : public pthread
457 {
458   public:
459   static pthread *get_null_pthread();
460   ~pthread_null();
461
462   /* From pthread These should never get called
463   * as the ojbect is not verifyable
464   */
465   void create (void *(*)(void *), pthread_attr *, void *);
466   void exit (void *value_ptr) __attribute__ ((noreturn));
467   int cancel ();
468   void testcancel ();
469   int setcancelstate (int state, int *oldstate);
470   int setcanceltype (int type, int *oldtype);
471   void push_cleanup_handler (__pthread_cleanup_handler *handler);
472   void pop_cleanup_handler (int const execute);
473   unsigned long getsequence_np();
474
475   private:
476   pthread_null ();
477   static pthread_null _instance;
478 };
479
480 class pthread_condattr: public verifyable_object
481 {
482 public:
483   static bool is_good_object(pthread_condattr_t const *);
484   int shared;
485
486   pthread_condattr ();
487   ~pthread_condattr ();
488 };
489
490 class pthread_cond: public verifyable_object
491 {
492 public:
493   static bool is_good_object (pthread_cond_t const *);
494   static bool is_good_initializer (pthread_cond_t const *);
495   static bool is_good_initializer_or_object (pthread_cond_t const *);
496   static bool is_good_initializer_or_bad_object (pthread_cond_t const *);
497   static void init_mutex ();
498   static int init (pthread_cond_t *, const pthread_condattr_t *);
499
500   int shared;
501
502   unsigned long waiting;
503   unsigned long pending;
504   HANDLE sem_wait;
505
506   pthread_mutex mtx_in;
507   pthread_mutex mtx_out;
508
509   pthread_mutex_t mtx_cond;
510
511   void unblock (const bool all);
512   int wait (pthread_mutex_t mutex, DWORD dwMilliseconds = INFINITE);
513
514   pthread_cond (pthread_condattr *);
515   ~pthread_cond ();
516
517   class pthread_cond * next;
518   static void fixup_after_fork ()
519   {
520     conds.fixup_after_fork ();
521     conds.for_each (&pthread_cond::_fixup_after_fork);
522   }
523
524 private:
525   void _fixup_after_fork ();
526
527   static List<pthread_cond> conds;
528   static fast_mutex cond_initialization_lock;
529 };
530
531 class pthread_rwlockattr: public verifyable_object
532 {
533 public:
534   static bool is_good_object(pthread_rwlockattr_t const *);
535   int shared;
536
537   pthread_rwlockattr ();
538   ~pthread_rwlockattr ();
539 };
540
541 class pthread_rwlock: public verifyable_object
542 {
543 public:
544   static bool is_good_object (pthread_rwlock_t const *);
545   static bool is_good_initializer (pthread_rwlock_t const *);
546   static bool is_good_initializer_or_object (pthread_rwlock_t const *);
547   static bool is_good_initializer_or_bad_object (pthread_rwlock_t const *);
548   static void init_mutex ();
549   static int init (pthread_rwlock_t *, const pthread_rwlockattr_t *);
550
551   int shared;
552
553   unsigned long waiting_readers;
554   unsigned long waiting_writers;
555   pthread_t writer;
556   struct RWLOCK_READER
557   {
558     struct RWLOCK_READER *next;
559     pthread_t thread;
560   } *readers;
561   fast_mutex readers_mx;
562
563   int rdlock ();
564   int tryrdlock ();
565
566   int wrlock ();
567   int trywrlock ();
568
569   int unlock ();
570
571   pthread_mutex mtx;
572   pthread_cond cond_readers;
573   pthread_cond cond_writers;
574
575   pthread_rwlock (pthread_rwlockattr *);
576   ~pthread_rwlock ();
577
578   class pthread_rwlock * next;
579   static void fixup_after_fork ()
580   {
581     rwlocks.fixup_after_fork ();
582     rwlocks.for_each (&pthread_rwlock::_fixup_after_fork);
583   }
584
585 private:
586   static List<pthread_rwlock> rwlocks;
587
588   void add_reader (struct RWLOCK_READER *rd);
589   void remove_reader (struct RWLOCK_READER *rd);
590   struct RWLOCK_READER *lookup_reader (pthread_t thread);
591
592   void release ()
593   {
594     if (waiting_writers)
595       {
596         if (!readers)
597           cond_writers.unblock (false);
598       }
599     else if (waiting_readers)
600       cond_readers.unblock (true);
601   }
602
603
604   static void rdlock_cleanup (void *arg);
605   static void wrlock_cleanup (void *arg);
606
607   void _fixup_after_fork ();
608
609   static fast_mutex rwlock_initialization_lock;
610 };
611
612 class pthread_once
613 {
614 public:
615   pthread_mutex_t mutex;
616   int state;
617 };
618
619 /* shouldn't be here */
620 class semaphore: public verifyable_object
621 {
622 public:
623   static bool is_good_object(sem_t const *);
624   /* API calls */
625   static int init (sem_t * sem, int pshared, unsigned int value);
626   static int destroy (sem_t * sem);
627   static sem_t *open (const char *name, int oflag, mode_t mode,
628                       unsigned int value);
629   static int wait (sem_t * sem);
630   static int post (sem_t * sem);
631   static int getvalue (sem_t * sem, int *sval);
632   static int trywait (sem_t * sem);
633   static int timedwait (sem_t * sem, const struct timespec *abstime);
634
635   HANDLE win32_obj_id;
636   int shared;
637   long currentvalue;
638   char *name;
639
640   semaphore (int, unsigned int);
641   semaphore (const char *name, int oflag, mode_t mode, unsigned int value);
642   ~semaphore ();
643
644   class semaphore * next;
645   static void fixup_after_fork ()
646   {
647     semaphores.fixup_after_fork ();
648     semaphores.for_each (&semaphore::_fixup_after_fork);
649   }
650
651 private:
652   void _wait ();
653   void _post ();
654   int _getvalue (int *sval);
655   int _trywait ();
656   int _timedwait (const struct timespec *abstime);
657
658   void _fixup_after_fork ();
659
660   static List<semaphore> semaphores;
661 };
662
663 class callback
664 {
665 public:
666   void (*cb)(void);
667   class callback * next;
668 };
669
670 struct MTinterface
671 {
672   // General
673   int concurrency;
674   long int threadcount;
675
676   callback *pthread_prepare;
677   callback *pthread_child;
678   callback *pthread_parent;
679
680   void Init ();
681   void fixup_before_fork (void);
682   void fixup_after_fork (void);
683
684 #if 0 // avoid initialization since zero is implied and
685   MTinterface () :
686     concurrency (0), threadcount (0),
687     pthread_prepare (NULL), pthread_child (NULL), pthread_parent (NULL)
688   {
689   }
690 #endif
691 };
692
693 #define MT_INTERFACE user_data->threadinterface
694 #endif // _CYGNUS_THREADS_