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