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