]> sourceware.org Git - newlib-cygwin.git/blame - winsup/cygwin/thread.h
* speclib: Use correct EOF marker. Ensure that directory is actually deleted
[newlib-cygwin.git] / winsup / cygwin / thread.h
CommitLineData
1fd5e000
CF
1/* thread.h: Locking and threading module definitions
2
e136dbc2 3 Copyright 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
1fd5e000
CF
4
5 Written by Marco Fuykschot <marco@ddi.nl>
9a08b2c0 6 Major update 2001 Robert Collins <rbtcollins@hotmail.com>
462f4eff 7
1fd5e000
CF
8This file is part of Cygwin.
9
10This software is a copyrighted work licensed under the terms of the
11Cygwin license. Please consult the file "CYGWIN_LICENSE" for
12details. */
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
1fd5e000
CF
21
22#define WRITE_LOCK 1
23#define READ_LOCK 2
24
25extern "C"
26{
27#if defined (_CYG_THREAD_FAILSAFE) && defined (_MT_SAFE)
5c83f260 28 void AssertResourceOwner (int, int);
1fd5e000 29#else
f2aeff27 30#define AssertResourceOwner(i,ii)
1fd5e000
CF
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
5c83f260 41#include <pthread.h>
2ff03dc2
TP
42#include <limits.h>
43#include <errno.h>
9a08b2c0 44#include <signal.h>
1fd5e000
CF
45#include <pwd.h>
46#include <grp.h>
28194e81 47#include <security.h>
bccd5e0d 48#define _NOMNTENT_FUNCS
1fd5e000 49#include <mntent.h>
1fd5e000 50
9a08b2c0 51extern "C"
1fd5e000 52{
9a08b2c0 53
f2aeff27
CF
54struct _winsup_t
55{
56 /*
5c83f260
RC
57 Needed for the group functions
58 */
de4e0d30 59 struct __group16 _grp;
f2aeff27
CF
60 char *_namearray[2];
61 int _grp_pos;
62
63 /* console.cc */
64 unsigned _rarg;
65
66 /* dlfcn.cc */
67 int _dl_error;
68 char _dl_buffer[256];
69
70 /* passwd.cc */
71 struct passwd _res;
72 char _pass[_PASSWORD_LEN];
73 int _pw_pos;
74
75 /* path.cc */
76 struct mntent mntbuf;
77 int _iteration;
78 DWORD available_drives;
f97adf98
CF
79 char mnt_type[80];
80 char mnt_opts[80];
95d02d5b
RC
81 char mnt_fsname[CYG_MAX_PATH];
82 char mnt_dir[CYG_MAX_PATH];
f2aeff27
CF
83
84 /* strerror */
85 char _strerror_buf[20];
86
87 /* sysloc.cc */
88 char *_process_ident;
89 int _process_logopt;
90 int _process_facility;
91 int _process_logmask;
92
93 /* times.cc */
94 char timezone_buf[20];
95 struct tm _localtime_buf;
96
97 /* uinfo.cc */
17db1105 98 char _username[UNLEN + 1];
cb19ccf4
CV
99
100 /* net.cc */
101 char *_ntoa_buf;
102 struct protoent *_protoent_buf;
103 struct servent *_servent_buf;
104 struct hostent *_hostent_buf;
f2aeff27
CF
105};
106
107
108struct __reent_t
109{
110 struct _reent *_clib;
111 struct _winsup_t *_winsup;
370b1173 112 void init_clib (_reent&);
f2aeff27 113};
1fd5e000 114
f2aeff27
CF
115_winsup_t *_reent_winsup ();
116void SetResourceLock (int, int, const char *) __attribute__ ((regparm (3)));
117void ReleaseResourceLock (int, int, const char *)
118 __attribute__ ((regparm (3)));
1fd5e000
CF
119
120#ifdef _CYG_THREAD_FAILSAFE
f2aeff27 121void AssertResourceOwner (int, int);
1fd5e000
CF
122#else
123#define AssertResourceOwner(i,ii)
124#endif
125}
126
28194e81 127class fast_mutex
ed9fe455
TP
128{
129public:
28194e81
TP
130 fast_mutex () :
131 lock_counter (0), win32_obj_id (0)
132 {
133 }
134
135 ~fast_mutex ()
136 {
137 if(win32_obj_id)
138 CloseHandle (win32_obj_id);
139 }
140
141 bool init ()
142 {
7cba834b 143 lock_counter = 0;
28194e81
TP
144 win32_obj_id = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL);
145 if (!win32_obj_id)
146 {
147 debug_printf ("CreateSemaphore failed. %E");
148 return false;
149 }
150 return true;
151 }
152
153 void lock ()
154 {
155 if (InterlockedIncrement ((long *)&lock_counter) != 1)
156 WaitForSingleObject (win32_obj_id, INFINITE);
157 }
158
159 void unlock ()
160 {
161 if (InterlockedDecrement ((long *)&lock_counter))
162 ::ReleaseSemaphore (win32_obj_id, 1, NULL);
163 }
164
ed9fe455 165private:
28194e81
TP
166 unsigned long lock_counter;
167 HANDLE win32_obj_id;
ed9fe455
TP
168};
169
1fd5e000
CF
170class per_process;
171class pinfo;
172
173class ResourceLocks
174{
175public:
5c83f260
RC
176 ResourceLocks ()
177 {
178 }
1dc16fc7
CF
179 LPCRITICAL_SECTION Lock (int);
180 void Init ();
181 void Delete ();
1fd5e000 182#ifdef _CYG_THREAD_FAILSAFE
1dc16fc7
CF
183 DWORD owner;
184 DWORD count;
1fd5e000 185#endif
9a08b2c0 186private:
1dc16fc7
CF
187 CRITICAL_SECTION lock;
188 bool inited;
1fd5e000
CF
189};
190
9a08b2c0
CF
191#define PTHREAD_MAGIC 0xdf0df045
192#define PTHREAD_MUTEX_MAGIC PTHREAD_MAGIC+1
193#define PTHREAD_KEY_MAGIC PTHREAD_MAGIC+2
194#define PTHREAD_ATTR_MAGIC PTHREAD_MAGIC+3
195#define PTHREAD_MUTEXATTR_MAGIC PTHREAD_MAGIC+4
196#define PTHREAD_COND_MAGIC PTHREAD_MAGIC+5
197#define PTHREAD_CONDATTR_MAGIC PTHREAD_MAGIC+6
198#define SEM_MAGIC PTHREAD_MAGIC+7
2ff03dc2 199#define PTHREAD_ONCE_MAGIC PTHREAD_MAGIC+8
00d296a3
TP
200#define PTHREAD_RWLOCK_MAGIC PTHREAD_MAGIC+9
201#define PTHREAD_RWLOCKATTR_MAGIC PTHREAD_MAGIC+10
5c83f260 202
2ff03dc2 203#define MUTEX_OWNER_ANONYMOUS ((pthread_t) -1)
5d68d1de 204
5c83f260 205/* verifyable_object should not be defined here - it's a general purpose class */
1fd5e000 206
9a08b2c0
CF
207class verifyable_object
208{
209public:
210 long magic;
1fd5e000 211
aea1f301
CF
212 verifyable_object (long);
213 virtual ~verifyable_object ();
9a08b2c0
CF
214};
215
9c510edc 216typedef enum
86336f4f
RC
217{
218 VALID_OBJECT,
219 INVALID_OBJECT,
220 VALID_STATIC_OBJECT
221} verifyable_object_state;
222
223verifyable_object_state verifyable_object_isvalid (void const *, long);
224verifyable_object_state verifyable_object_isvalid (void const *, long, void *);
1fd5e000 225
28194e81
TP
226template <class list_node> inline void
227List_insert (fast_mutex &mx, list_node *&head, list_node *node)
228{
229 if (!node)
230 return;
231 mx.lock ();
232 node->next = head;
233 head = node;
234 mx.unlock ();
235}
236
237template <class list_node> inline void
238List_remove (fast_mutex &mx, list_node *&head, list_node *node)
239{
240 if (!node)
241 return;
242 mx.lock ();
243 if (node == head)
244 head = head->next;
245 else if (head)
246 {
247 list_node *cur = head;
248
249 while (cur->next && node != cur->next)
250 cur = cur->next;
251 if (node == cur->next)
252 cur->next = cur->next->next;
253 }
254 mx.unlock ();
255}
256
257
258template <class list_node> class List
259{
260 public:
9306ba2e
TP
261 List() : head(NULL)
262 {
28194e81 263 mx_init ();
9306ba2e
TP
264 }
265
28194e81 266 ~List()
9306ba2e 267 {
9306ba2e
TP
268 }
269
28194e81 270 void fixup_after_fork ()
9306ba2e 271 {
28194e81
TP
272 mx_init ();
273 }
15648790 274
28194e81
TP
275 void insert (list_node *node)
276 {
277 List_insert (mx, head, node);
9306ba2e
TP
278 }
279
28194e81 280 void remove (list_node *node)
9306ba2e 281 {
28194e81 282 List_remove (mx, head, node);
9306ba2e
TP
283 }
284
15648790 285 void for_each (void (list_node::*callback) ())
9306ba2e 286 {
28194e81
TP
287 mx.lock ();
288 list_node *cur = head;
289 while (cur)
9306ba2e 290 {
28194e81
TP
291 (cur->*callback) ();
292 cur = cur->next;
9306ba2e 293 }
28194e81 294 mx.unlock ();
9306ba2e
TP
295 }
296
af428c1e 297protected:
28194e81
TP
298 void mx_init ()
299 {
300 if (!mx.init ())
301 api_fatal ("Could not create mutex for list synchronisation.");
302 }
303
304 fast_mutex mx;
15648790 305 list_node *head;
af428c1e
RC
306};
307
5c83f260
RC
308class pthread_key:public verifyable_object
309{
310public:
15648790
TP
311 static bool is_good_object (pthread_key_t const *);
312 DWORD tls_index;
f1f13795 313
5c83f260 314 int set (const void *);
20b94ee9 315 void *get () const;
5c83f260 316
20b94ee9 317 pthread_key (void (*)(void *));
aea1f301 318 ~pthread_key ();
28194e81 319 static void fixup_before_fork ()
9306ba2e 320 {
28194e81 321 keys.for_each (&pthread_key::_fixup_before_fork);
9306ba2e
TP
322 }
323
28194e81 324 static void fixup_after_fork ()
9306ba2e 325 {
28194e81
TP
326 keys.fixup_after_fork ();
327 keys.for_each (&pthread_key::_fixup_after_fork);
9306ba2e
TP
328 }
329
15648790 330 static void run_all_destructors ()
9306ba2e 331 {
15648790 332 keys.for_each (&pthread_key::run_destructor);
9306ba2e 333 }
af428c1e
RC
334
335 /* List support calls */
336 class pthread_key *next;
f1f13795 337private:
af428c1e 338 static List<pthread_key> keys;
28194e81
TP
339 void _fixup_before_fork ();
340 void _fixup_after_fork ();
20b94ee9 341 void (*destructor) (void *);
15648790 342 void run_destructor ();
af428c1e 343 void *fork_buf;
5c83f260
RC
344};
345
9a08b2c0 346class pthread_attr:public verifyable_object
1fd5e000 347{
9a08b2c0 348public:
15648790 349 static bool is_good_object(pthread_attr_t const *);
9a08b2c0 350 int joinable;
5c83f260
RC
351 int contentionscope;
352 int inheritsched;
353 struct sched_param schedparam;
9a08b2c0
CF
354 size_t stacksize;
355
aea1f301
CF
356 pthread_attr ();
357 ~pthread_attr ();
1fd5e000
CF
358};
359
43c3c4e3
RC
360class pthread_mutexattr:public verifyable_object
361{
362public:
15648790 363 static bool is_good_object(pthread_mutexattr_t const *);
43c3c4e3
RC
364 int pshared;
365 int mutextype;
aea1f301
CF
366 pthread_mutexattr ();
367 ~pthread_mutexattr ();
43c3c4e3
RC
368};
369
370class pthread_mutex:public verifyable_object
371{
372public:
15648790
TP
373 static bool is_good_object (pthread_mutex_t const *);
374 static bool is_good_initializer (pthread_mutex_t const *);
375 static bool is_good_initializer_or_object (pthread_mutex_t const *);
376 static bool is_good_initializer_or_bad_object (pthread_mutex_t const *mutex);
377 static bool can_be_unlocked (pthread_mutex_t const *mutex);
378 static void init_mutex ();
eb208df0 379 static int init (pthread_mutex_t *, const pthread_mutexattr_t *);
9d1e72a1 380
2ff03dc2 381 unsigned long lock_counter;
43c3c4e3 382 HANDLE win32_obj_id;
5d68d1de 383 unsigned int recursion_counter;
43c3c4e3 384 LONG condwaits;
5d68d1de
TP
385 pthread_t owner;
386 int type;
43c3c4e3 387 int pshared;
43c3c4e3 388
15648790 389 pthread_t get_pthread_self () const
2ff03dc2
TP
390 {
391 return PTHREAD_MUTEX_NORMAL == type ? MUTEX_OWNER_ANONYMOUS :
392 ::pthread_self ();
393 }
394
15648790 395 int lock ()
2ff03dc2 396 {
15648790 397 return _lock (get_pthread_self ());
2ff03dc2 398 }
15648790 399 int trylock ()
2ff03dc2 400 {
15648790 401 return _trylock (get_pthread_self ());
2ff03dc2 402 }
15648790 403 int unlock ()
2ff03dc2 404 {
15648790 405 return _unlock (get_pthread_self ());
2ff03dc2 406 }
15648790 407 int destroy ()
2ff03dc2 408 {
15648790 409 return _destroy (get_pthread_self ());
2ff03dc2
TP
410 }
411
15648790 412 void set_owner (pthread_t self)
2ff03dc2
TP
413 {
414 recursion_counter = 1;
415 owner = self;
416 }
417
15648790 418 int lock_recursive ()
2ff03dc2
TP
419 {
420 if (UINT_MAX == recursion_counter)
421 return EAGAIN;
422 ++recursion_counter;
423 return 0;
424 }
425
43c3c4e3
RC
426 pthread_mutex (pthread_mutexattr * = NULL);
427 pthread_mutex (pthread_mutex_t *, pthread_mutexattr *);
428 ~pthread_mutex ();
ed9fe455 429
9306ba2e
TP
430 class pthread_mutex * next;
431 static void fixup_after_fork ()
432 {
28194e81 433 mutexes.fixup_after_fork ();
15648790 434 mutexes.for_each (&pthread_mutex::_fixup_after_fork);
9306ba2e
TP
435 }
436
eb208df0 437private:
15648790
TP
438 int _lock (pthread_t self);
439 int _trylock (pthread_t self);
440 int _unlock (pthread_t self);
441 int _destroy (pthread_t self);
442
443 void _fixup_after_fork ();
2ff03dc2 444
9306ba2e 445 static List<pthread_mutex> mutexes;
28194e81 446 static fast_mutex mutex_initialization_lock;
43c3c4e3
RC
447};
448
09cbb9d6
TP
449#define WAIT_CANCELED (WAIT_OBJECT_0 + 1)
450
9a08b2c0 451class pthread:public verifyable_object
1fd5e000
CF
452{
453public:
9a08b2c0
CF
454 HANDLE win32_obj_id;
455 class pthread_attr attr;
456 void *(*function) (void *);
1dc16fc7
CF
457 void *arg;
458 void *return_ptr;
c6e0f665 459 bool valid;
1dc16fc7 460 bool suspended;
5c83f260 461 int cancelstate, canceltype;
d288c1c7 462 HANDLE cancel_event;
e9259cb2 463 pthread_t joiner;
5c83f260 464
1dc16fc7
CF
465 /* signal handling */
466 struct sigaction *sigs;
467 sigset_t *sigmask;
468 LONG *sigtodo;
4e786173
RC
469 virtual void create (void *(*)(void *), pthread_attr *, void *);
470
aea1f301
CF
471 pthread ();
472 virtual ~pthread ();
9a08b2c0 473
c8fa3426 474 static void init_mainthread ();
15648790 475 static bool is_good_object(pthread_t const *);
aea1f301
CF
476 static void atforkprepare();
477 static void atforkparent();
478 static void atforkchild();
9a08b2c0 479
aea1f301
CF
480 /* API calls */
481 static int cancel (pthread_t);
482 static int join (pthread_t * thread, void **return_val);
483 static int detach (pthread_t * thread);
484 static int create (pthread_t * thread, const pthread_attr_t * attr,
01f58e41 485 void *(*start_routine) (void *), void *arg);
aea1f301
CF
486 static int once (pthread_once_t *, void (*)(void));
487 static int atfork(void (*)(void), void (*)(void), void (*)(void));
488 static int suspend (pthread_t * thread);
489 static int resume (pthread_t * thread);
01f58e41 490
aea1f301 491 virtual void exit (void *value_ptr);
d288c1c7 492
aea1f301 493 virtual int cancel ();
9d1e72a1 494
aea1f301
CF
495 virtual void testcancel ();
496 static void static_cancel_self ();
d288c1c7 497
09cbb9d6
TP
498 static DWORD cancelable_wait (HANDLE object, DWORD timeout, const bool do_cancel = true);
499
aea1f301
CF
500 virtual int setcancelstate (int state, int *oldstate);
501 virtual int setcanceltype (int type, int *oldtype);
d288c1c7 502
aea1f301
CF
503 virtual void push_cleanup_handler (__pthread_cleanup_handler *handler);
504 virtual void pop_cleanup_handler (int const execute);
007276b3 505
aea1f301
CF
506 static pthread* self ();
507 static void *thread_init_wrapper (void *);
007276b3 508
aea1f301 509 virtual unsigned long getsequence_np();
4e786173 510
a4cea440
TP
511 static int equal (pthread_t t1, pthread_t t2)
512 {
513 return t1 == t2;
514 }
515
e1e196a2
TP
516 /* List support calls */
517 class pthread *next;
518 static void fixup_after_fork ()
519 {
28194e81 520 threads.fixup_after_fork ();
e1e196a2
TP
521 threads.for_each (&pthread::_fixup_after_fork);
522 }
523
c6e0f665
TP
524 static void suspend_all_except_self ()
525 {
526 threads.for_each (&pthread::suspend_except_self);
527 }
528
529 static void resume_all ()
530 {
531 threads.for_each (&pthread::resume);
532 }
533
9a08b2c0 534private:
e1e196a2 535 static List<pthread> threads;
aea1f301
CF
536 DWORD thread_id;
537 __pthread_cleanup_handler *cleanup_stack;
538 pthread_mutex mutex;
539
c6e0f665
TP
540 void suspend_except_self ();
541 void resume ();
542
e1e196a2
TP
543 void _fixup_after_fork ();
544
aea1f301
CF
545 void pop_all_cleanup_handlers (void);
546 void precreate (pthread_attr *);
547 void postcreate ();
15648790
TP
548 void set_thread_id_to_current ();
549 static void set_tls_self_pointer (pthread *);
550 static pthread *get_tls_self_pointer ();
aea1f301 551 void cancel_self ();
15648790
TP
552 DWORD get_thread_id ();
553 void init_current_thread ();
4e786173
RC
554};
555
15648790 556class pthread_null : public pthread
4e786173 557{
d04cf16c 558 public:
15648790
TP
559 static pthread *get_null_pthread();
560 ~pthread_null();
aea1f301
CF
561
562 /* From pthread These should never get called
563 * as the ojbect is not verifyable
564 */
565 void create (void *(*)(void *), pthread_attr *, void *);
566 void exit (void *value_ptr);
567 int cancel ();
568 void testcancel ();
569 int setcancelstate (int state, int *oldstate);
570 int setcanceltype (int type, int *oldtype);
571 void push_cleanup_handler (__pthread_cleanup_handler *handler);
572 void pop_cleanup_handler (int const execute);
573 unsigned long getsequence_np();
4e786173
RC
574
575 private:
15648790
TP
576 pthread_null ();
577 static pthread_null _instance;
1fd5e000
CF
578};
579
9a08b2c0 580class pthread_condattr:public verifyable_object
1fd5e000
CF
581{
582public:
15648790 583 static bool is_good_object(pthread_condattr_t const *);
1dc16fc7 584 int shared;
9a08b2c0 585
462f4eff
CF
586 pthread_condattr ();
587 ~pthread_condattr ();
1fd5e000
CF
588};
589
9a08b2c0 590class pthread_cond:public verifyable_object
5ccbf4b6
CF
591{
592public:
15648790
TP
593 static bool is_good_object (pthread_cond_t const *);
594 static bool is_good_initializer (pthread_cond_t const *);
595 static bool is_good_initializer_or_object (pthread_cond_t const *);
596 static bool is_good_initializer_or_bad_object (pthread_cond_t const *);
597 static void init_mutex ();
ed9fe455
TP
598 static int init (pthread_cond_t *, const pthread_condattr_t *);
599
5ccbf4b6 600 int shared;
f592b05d
TP
601
602 unsigned long waiting;
603 unsigned long pending;
15648790 604 HANDLE sem_wait;
f592b05d 605
15648790
TP
606 pthread_mutex mtx_in;
607 pthread_mutex mtx_out;
f592b05d 608
15648790 609 pthread_mutex_t mtx_cond;
f592b05d 610
15648790
TP
611 void unblock (const bool all);
612 int wait (pthread_mutex_t mutex, DWORD dwMilliseconds = INFINITE);
9a08b2c0 613
aea1f301
CF
614 pthread_cond (pthread_condattr *);
615 ~pthread_cond ();
ed9fe455 616
9306ba2e
TP
617 class pthread_cond * next;
618 static void fixup_after_fork ()
619 {
28194e81 620 conds.fixup_after_fork ();
15648790 621 conds.for_each (&pthread_cond::_fixup_after_fork);
9306ba2e
TP
622 }
623
ed9fe455 624private:
15648790
TP
625 void _fixup_after_fork ();
626
9306ba2e 627 static List<pthread_cond> conds;
28194e81 628 static fast_mutex cond_initialization_lock;
5c83f260
RC
629};
630
00d296a3
TP
631class pthread_rwlockattr:public verifyable_object
632{
633public:
15648790 634 static bool is_good_object(pthread_rwlockattr_t const *);
00d296a3
TP
635 int shared;
636
637 pthread_rwlockattr ();
638 ~pthread_rwlockattr ();
639};
640
641class pthread_rwlock:public verifyable_object
642{
643public:
15648790
TP
644 static bool is_good_object (pthread_rwlock_t const *);
645 static bool is_good_initializer (pthread_rwlock_t const *);
646 static bool is_good_initializer_or_object (pthread_rwlock_t const *);
647 static bool is_good_initializer_or_bad_object (pthread_rwlock_t const *);
648 static void init_mutex ();
00d296a3
TP
649 static int init (pthread_rwlock_t *, const pthread_rwlockattr_t *);
650
651 int shared;
652
15648790
TP
653 unsigned long waiting_readers;
654 unsigned long waiting_writers;
00d296a3
TP
655 pthread_t writer;
656 struct RWLOCK_READER
657 {
658 struct RWLOCK_READER *next;
659 pthread_t thread;
660 } *readers;
28194e81 661 fast_mutex readers_mx;
00d296a3 662
15648790
TP
663 int rdlock ();
664 int tryrdlock ();
00d296a3 665
15648790
TP
666 int wrlock ();
667 int trywrlock ();
00d296a3 668
15648790 669 int unlock ();
00d296a3
TP
670
671 pthread_mutex mtx;
15648790
TP
672 pthread_cond cond_readers;
673 pthread_cond cond_writers;
00d296a3 674
00d296a3
TP
675 pthread_rwlock (pthread_rwlockattr *);
676 ~pthread_rwlock ();
677
9306ba2e
TP
678 class pthread_rwlock * next;
679 static void fixup_after_fork ()
680 {
28194e81 681 rwlocks.fixup_after_fork ();
15648790 682 rwlocks.for_each (&pthread_rwlock::_fixup_after_fork);
9306ba2e
TP
683 }
684
00d296a3 685private:
9306ba2e
TP
686 static List<pthread_rwlock> rwlocks;
687
15648790
TP
688 void add_reader (struct RWLOCK_READER *rd);
689 void remove_reader (struct RWLOCK_READER *rd);
690 struct RWLOCK_READER *lookup_reader (pthread_t thread);
00d296a3 691
ffb576fb
TP
692 void release ()
693 {
694 if (waiting_writers)
695 {
696 if (!readers)
697 cond_writers.unblock (false);
698 }
699 else if (waiting_readers)
700 cond_readers.unblock (true);
701 }
702
703
15648790
TP
704 static void rdlock_cleanup (void *arg);
705 static void wrlock_cleanup (void *arg);
00d296a3 706
15648790
TP
707 void _fixup_after_fork ();
708
28194e81 709 static fast_mutex rwlock_initialization_lock;
00d296a3
TP
710};
711
5c83f260
RC
712class pthread_once
713{
714public:
715 pthread_mutex_t mutex;
716 int state;
5ccbf4b6 717};
1fd5e000 718
9a08b2c0
CF
719/* shouldn't be here */
720class semaphore:public verifyable_object
1fd5e000 721{
9a08b2c0 722public:
15648790 723 static bool is_good_object(sem_t const *);
01f58e41
RC
724 /* API calls */
725 static int init (sem_t * sem, int pshared, unsigned int value);
726 static int destroy (sem_t * sem);
07233966
CV
727 static sem_t *open (const char *name, int oflag, mode_t mode,
728 unsigned int value);
01f58e41 729 static int wait (sem_t * sem);
01f58e41 730 static int post (sem_t * sem);
07233966
CV
731 static int getvalue (sem_t * sem, int *sval);
732 static int trywait (sem_t * sem);
733 static int timedwait (sem_t * sem, const struct timespec *abstime);
9d1e72a1 734
9a08b2c0
CF
735 HANDLE win32_obj_id;
736 int shared;
f9229ef7 737 long currentvalue;
07233966 738 char *name;
9a08b2c0 739
aea1f301 740 semaphore (int, unsigned int);
07233966 741 semaphore (const char *name, int oflag, mode_t mode, unsigned int value);
aea1f301 742 ~semaphore ();
9306ba2e
TP
743
744 class semaphore * next;
745 static void fixup_after_fork ()
746 {
28194e81 747 semaphores.fixup_after_fork ();
15648790 748 semaphores.for_each (&semaphore::_fixup_after_fork);
9306ba2e
TP
749 }
750
9306ba2e 751private:
15648790
TP
752 void _wait ();
753 void _post ();
07233966 754 int _getvalue (int *sval);
15648790 755 int _trywait ();
07233966 756 int _timedwait (const struct timespec *abstime);
15648790
TP
757
758 void _fixup_after_fork ();
759
9306ba2e 760 static List<semaphore> semaphores;
9a08b2c0
CF
761};
762
39b6859a
CF
763class callback
764{
765public:
766 void (*cb)(void);
767 class callback * next;
768};
769
1fd5e000
CF
770class MTinterface
771{
772public:
1dc16fc7 773 // General
5c83f260 774 int concurrency;
e6b98fc8 775 long int threadcount;
1fd5e000 776
1dc16fc7
CF
777 // Used for main thread data, and sigproc thread
778 struct __reent_t reents;
779 struct _winsup_t winsup_reent;
1fd5e000 780
39b6859a
CF
781 callback *pthread_prepare;
782 callback *pthread_child;
783 callback *pthread_parent;
5c83f260 784
f8c8e13b
RC
785 pthread_key reent_key;
786 pthread_key thread_self_key;
787
c8fa3426 788 void Init ();
f1f13795 789 void fixup_before_fork (void);
f9229ef7 790 void fixup_after_fork (void);
1fd5e000 791
f8c8e13b
RC
792 MTinterface () :
793 concurrency (0), threadcount (1),
794 pthread_prepare (NULL), pthread_child (NULL), pthread_parent (NULL),
f8c8e13b 795 reent_key (NULL), thread_self_key (NULL)
aea1f301 796 {
aea1f301 797 }
1fd5e000
CF
798};
799
f8c8e13b
RC
800#define MT_INTERFACE user_data->threadinterface
801
b0e82b74 802#endif // MT_SAFE
1fd5e000 803
b0e82b74 804#endif // _CYGNUS_THREADS_
This page took 0.306942 seconds and 5 git commands to generate.