1 /* thread.h: Locking and threading module definitions
3 Copyright 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
5 Written by Marco Fuykschot <marco@ddi.nl>
6 Major update 2001 Robert Collins <rbtcollins@hotmail.com>
8 This file is part of Cygwin.
10 This software is a copyrighted work licensed under the terms of the
11 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
14 #ifndef _CYGNUS_THREADS_
15 #define _CYGNUS_THREADS_
17 #define LOCK_FD_LIST 1
18 #define LOCK_MEMORY_LIST 2
19 #define LOCK_MMAP_LIST 3
20 #define LOCK_DLL_LIST 4
27 #if defined (_CYG_THREAD_FAILSAFE) && defined (_MT_SAFE)
28 void AssertResourceOwner (int, int);
30 #define AssertResourceOwner(i,ii)
36 #define SetResourceLock(i,n,c)
37 #define ReleaseResourceLock(i,n,c)
47 #define _NOMNTENT_FUNCS
56 Needed for the group functions
58 struct __group16 _grp
;
71 char _pass
[_PASSWORD_LEN
];
77 DWORD available_drives
;
80 char mnt_fsname
[MAX_PATH
];
81 char mnt_dir
[MAX_PATH
];
84 char _strerror_buf
[20];
89 int _process_facility
;
93 char timezone_buf
[20];
94 struct tm _localtime_buf
;
97 char _username
[UNLEN
+ 1];
101 struct protoent
*_protoent_buf
;
102 struct servent
*_servent_buf
;
103 struct hostent
*_hostent_buf
;
109 struct _reent
*_clib
;
110 struct _winsup_t
*_winsup
;
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)));
118 #ifdef _CYG_THREAD_FAILSAFE
119 void AssertResourceOwner (int, int);
121 #define AssertResourceOwner(i,ii)
144 LPCRITICAL_SECTION
Lock (int);
147 #ifdef _CYG_THREAD_FAILSAFE
152 CRITICAL_SECTION lock
;
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
168 #define MUTEX_OWNER_ANONYMOUS ((pthread_t) -1)
170 /* verifyable_object should not be defined here - it's a general purpose class */
172 class verifyable_object
177 verifyable_object (long);
178 virtual ~verifyable_object ();
186 } verifyable_object_state
;
188 verifyable_object_state
verifyable_object_isvalid (void const *, long);
189 verifyable_object_state
verifyable_object_isvalid (void const *, long, void *);
191 template <class list_node
> class List
{
197 void insert (list_node
*node
)
201 node
->next
= (list_node
*) InterlockedExchangePointer (&head
, node
);
204 list_node
*remove ( list_node
*node
)
211 list_node
*result_prev
= head
;
212 while (result_prev
&& result_prev
->next
&& !(node
== result_prev
->next
))
213 result_prev
= result_prev
->next
;
215 return (list_node
*)InterlockedExchangePointer (&result_prev
->next
, result_prev
->next
->next
);
221 return (list_node
*) InterlockedExchangePointer (&head
, head
->next
);
224 /* poor mans generic programming. */
225 void for_each (void (list_node::*callback
) ())
227 list_node
*node
= head
;
230 (node
->*callback
) ();
239 class pthread_key
:public verifyable_object
242 static bool is_good_object (pthread_key_t
const *);
245 int set (const void *);
248 pthread_key (void (*)(void *));
250 static void fixup_before_fork()
252 keys
.for_each (&pthread_key::save_key_to_buffer
);
255 static void fixup_after_fork()
257 keys
.for_each (&pthread_key::recreate_key_from_buffer
);
260 static void run_all_destructors ()
262 keys
.for_each (&pthread_key::run_destructor
);
265 /* List support calls */
266 class pthread_key
*next
;
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 ();
276 class pthread_attr
:public verifyable_object
279 static bool is_good_object(pthread_attr_t
const *);
283 struct sched_param schedparam
;
290 class pthread_mutexattr
:public verifyable_object
293 static bool is_good_object(pthread_mutexattr_t
const *);
296 pthread_mutexattr ();
297 ~pthread_mutexattr ();
300 class pthread_mutex
:public verifyable_object
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
*);
311 unsigned long lock_counter
;
313 unsigned int recursion_counter
;
319 pthread_t
get_pthread_self () const
321 return PTHREAD_MUTEX_NORMAL
== type
? MUTEX_OWNER_ANONYMOUS
:
327 return _lock (get_pthread_self ());
331 return _trylock (get_pthread_self ());
335 return _unlock (get_pthread_self ());
339 return _destroy (get_pthread_self ());
342 void set_owner (pthread_t self
)
344 recursion_counter
= 1;
348 int lock_recursive ()
350 if (UINT_MAX
== recursion_counter
)
356 pthread_mutex (pthread_mutexattr
* = NULL
);
357 pthread_mutex (pthread_mutex_t
*, pthread_mutexattr
*);
360 class pthread_mutex
* next
;
361 static void fixup_after_fork ()
363 mutexes
.for_each (&pthread_mutex::_fixup_after_fork
);
367 int _lock (pthread_t self
);
368 int _trylock (pthread_t self
);
369 int _unlock (pthread_t self
);
370 int _destroy (pthread_t self
);
372 void _fixup_after_fork ();
374 static List
<pthread_mutex
> mutexes
;
375 static native_mutex mutex_initialization_lock
;
378 #define WAIT_CANCELED (WAIT_OBJECT_0 + 1)
380 class pthread
:public verifyable_object
384 class pthread_attr attr
;
385 void *(*function
) (void *);
389 int cancelstate
, canceltype
;
394 /* signal handling */
395 struct sigaction
*sigs
;
398 virtual void create (void *(*)(void *), pthread_attr
*, void *);
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();
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
);
420 virtual void exit (void *value_ptr
);
422 virtual int cancel ();
424 virtual void testcancel ();
425 static void static_cancel_self ();
427 static DWORD
cancelable_wait (HANDLE object
, DWORD timeout
, const bool do_cancel
= true);
429 virtual int setcancelstate (int state
, int *oldstate
);
430 virtual int setcanceltype (int type
, int *oldtype
);
432 virtual void push_cleanup_handler (__pthread_cleanup_handler
*handler
);
433 virtual void pop_cleanup_handler (int const execute
);
435 static pthread
* self ();
436 static void *thread_init_wrapper (void *);
438 virtual unsigned long getsequence_np();
440 static int equal (pthread_t t1
, pthread_t t2
)
447 __pthread_cleanup_handler
*cleanup_stack
;
450 void pop_all_cleanup_handlers (void);
451 void precreate (pthread_attr
*);
453 void set_thread_id_to_current ();
454 static void set_tls_self_pointer (pthread
*);
455 static pthread
*get_tls_self_pointer ();
457 DWORD
get_thread_id ();
458 void init_current_thread ();
461 class pthread_null
: public pthread
464 static pthread
*get_null_pthread();
467 /* From pthread These should never get called
468 * as the ojbect is not verifyable
470 void create (void *(*)(void *), pthread_attr
*, void *);
471 void exit (void *value_ptr
);
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();
482 static pthread_null _instance
;
485 class pthread_condattr
:public verifyable_object
488 static bool is_good_object(pthread_condattr_t
const *);
492 ~pthread_condattr ();
495 class pthread_cond
:public verifyable_object
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
*);
507 unsigned long waiting
;
508 unsigned long pending
;
511 pthread_mutex mtx_in
;
512 pthread_mutex mtx_out
;
514 pthread_mutex_t mtx_cond
;
516 void unblock (const bool all
);
517 int wait (pthread_mutex_t mutex
, DWORD dwMilliseconds
= INFINITE
);
519 pthread_cond (pthread_condattr
*);
522 class pthread_cond
* next
;
523 static void fixup_after_fork ()
525 conds
.for_each (&pthread_cond::_fixup_after_fork
);
529 void _fixup_after_fork ();
531 static List
<pthread_cond
> conds
;
532 static native_mutex cond_initialization_lock
;
535 class pthread_rwlockattr
:public verifyable_object
538 static bool is_good_object(pthread_rwlockattr_t
const *);
541 pthread_rwlockattr ();
542 ~pthread_rwlockattr ();
545 class pthread_rwlock
:public verifyable_object
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
*);
557 unsigned long waiting_readers
;
558 unsigned long waiting_writers
;
562 struct RWLOCK_READER
*next
;
575 pthread_cond cond_readers
;
576 pthread_cond cond_writers
;
578 pthread_rwlock (pthread_rwlockattr
*);
581 class pthread_rwlock
* next
;
582 static void fixup_after_fork ()
584 rwlocks
.for_each (&pthread_rwlock::_fixup_after_fork
);
588 static List
<pthread_rwlock
> rwlocks
;
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
);
599 cond_writers
.unblock (false);
601 else if (waiting_readers
)
602 cond_readers
.unblock (true);
606 static void rdlock_cleanup (void *arg
);
607 static void wrlock_cleanup (void *arg
);
609 void _fixup_after_fork ();
611 static native_mutex rwlock_initialization_lock
;
617 pthread_mutex_t mutex
;
621 /* shouldn't be here */
622 class semaphore
:public verifyable_object
625 static bool is_good_object(sem_t
const *);
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
);
637 semaphore (int, unsigned int);
640 class semaphore
* next
;
641 static void fixup_after_fork ()
643 semaphores
.for_each (&semaphore::_fixup_after_fork
);
651 void _fixup_after_fork ();
653 static List
<semaphore
> semaphores
;
660 class callback
* next
;
668 long int threadcount
;
670 // Used for main thread data, and sigproc thread
671 struct __reent_t reents
;
672 struct _winsup_t winsup_reent
;
674 callback
*pthread_prepare
;
675 callback
*pthread_child
;
676 callback
*pthread_parent
;
678 pthread_key reent_key
;
679 pthread_key thread_self_key
;
682 void fixup_before_fork (void);
683 void fixup_after_fork (void);
686 concurrency (0), threadcount (1),
687 pthread_prepare (NULL
), pthread_child (NULL
), pthread_parent (NULL
),
688 reent_key (NULL
), thread_self_key (NULL
)
693 #define MT_INTERFACE user_data->threadinterface
697 #endif // _CYGNUS_THREADS_