]> sourceware.org Git - newlib-cygwin.git/blob - winsup/cygwin/thread.h
2002-09-21 Robert Collins <rbtcollins@hotmail.com>
[newlib-cygwin.git] / winsup / cygwin / thread.h
1 /* thread.h: Locking and threading module definitions
2
3 Copyright 1998, 1999, 2000, 2001, 2002 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 <signal.h>
43 #include <pwd.h>
44 #include <grp.h>
45 #define _NOMNTENT_FUNCS
46 #include <mntent.h>
47
48 extern "C"
49 {
50
51 struct _winsup_t
52 {
53 /*
54 Needed for the group functions
55 */
56 struct __group16 _grp;
57 char *_namearray[2];
58 int _grp_pos;
59
60 /* console.cc */
61 unsigned _rarg;
62
63 /* dlfcn.cc */
64 int _dl_error;
65 char _dl_buffer[256];
66
67 /* passwd.cc */
68 struct passwd _res;
69 char _pass[_PASSWORD_LEN];
70 int _pw_pos;
71
72 /* path.cc */
73 struct mntent mntbuf;
74 int _iteration;
75 DWORD available_drives;
76 char mnt_type[80];
77 char mnt_opts[80];
78 char mnt_fsname[MAX_PATH];
79 char mnt_dir[MAX_PATH];
80
81 /* strerror */
82 char _strerror_buf[20];
83
84 /* sysloc.cc */
85 char *_process_ident;
86 int _process_logopt;
87 int _process_facility;
88 int _process_logmask;
89
90 /* times.cc */
91 char timezone_buf[20];
92 struct tm _localtime_buf;
93
94 /* uinfo.cc */
95 char _username[UNLEN + 1];
96
97 /* net.cc */
98 char *_ntoa_buf;
99 struct protoent *_protoent_buf;
100 struct servent *_servent_buf;
101 struct hostent *_hostent_buf;
102 };
103
104
105 struct __reent_t
106 {
107 struct _reent *_clib;
108 struct _winsup_t *_winsup;
109 };
110
111 _reent *_reent_clib ();
112 _winsup_t *_reent_winsup ();
113 void SetResourceLock (int, int, const char *) __attribute__ ((regparm (3)));
114 void ReleaseResourceLock (int, int, const char *)
115 __attribute__ ((regparm (3)));
116
117 #ifdef _CYG_THREAD_FAILSAFE
118 void AssertResourceOwner (int, int);
119 #else
120 #define AssertResourceOwner(i,ii)
121 #endif
122 }
123
124 class per_process;
125 class pinfo;
126
127 class ResourceLocks
128 {
129 public:
130 ResourceLocks ()
131 {
132 }
133 LPCRITICAL_SECTION Lock (int);
134 void Init ();
135 void Delete ();
136 #ifdef _CYG_THREAD_FAILSAFE
137 DWORD owner;
138 DWORD count;
139 #endif
140 private:
141 CRITICAL_SECTION lock;
142 bool inited;
143 };
144
145 #define PTHREAD_MAGIC 0xdf0df045
146 #define PTHREAD_MUTEX_MAGIC PTHREAD_MAGIC+1
147 #define PTHREAD_KEY_MAGIC PTHREAD_MAGIC+2
148 #define PTHREAD_ATTR_MAGIC PTHREAD_MAGIC+3
149 #define PTHREAD_MUTEXATTR_MAGIC PTHREAD_MAGIC+4
150 #define PTHREAD_COND_MAGIC PTHREAD_MAGIC+5
151 #define PTHREAD_CONDATTR_MAGIC PTHREAD_MAGIC+6
152 #define SEM_MAGIC PTHREAD_MAGIC+7
153 #define PTHREAD_ONCE_MAGIC PTHREAD_MAGIC+8;
154
155 /* verifyable_object should not be defined here - it's a general purpose class */
156
157 class verifyable_object
158 {
159 public:
160 long magic;
161
162 verifyable_object (long);
163 ~verifyable_object ();
164 };
165
166 typedef enum
167 {
168 VALID_OBJECT,
169 INVALID_OBJECT,
170 VALID_STATIC_OBJECT
171 } verifyable_object_state;
172
173 verifyable_object_state verifyable_object_isvalid (void const *, long);
174 verifyable_object_state verifyable_object_isvalid (void const *, long, void *);
175
176 /* interface */
177 template <class ListNode> class List {
178 public:
179 List();
180 void Insert (ListNode *aNode);
181 ListNode *Remove ( ListNode *aNode);
182 ListNode *Pop ();
183 void forEach (void (*)(ListNode *aNode));
184 protected:
185 ListNode *head;
186 };
187
188 class pthread_key:public verifyable_object
189 {
190 public:
191 static bool isGoodObject (pthread_key_t const *);
192 static void runAllDestructors ();
193
194 DWORD dwTlsIndex;
195
196 int set (const void *);
197 void *get () const;
198
199 pthread_key (void (*)(void *));
200 ~pthread_key ();
201 static void fixup_before_fork();
202 static void fixup_after_fork();
203
204 /* List support calls */
205 class pthread_key *next;
206 private:
207 // lists of objects. USE THREADSAFE INSERTS AND DELETES.
208 static List<pthread_key> keys;
209 static void saveAKey (pthread_key *);
210 static void restoreAKey (pthread_key *);
211 static void destroyAKey (pthread_key *);
212 void saveKeyToBuffer ();
213 void recreateKeyFromBuffer ();
214 void (*destructor) (void *);
215 void run_destructor () const;
216 void *fork_buf;
217 };
218
219 /* implementation */
220 template <class ListNode>
221 List<ListNode>::List<ListNode> () : head(NULL)
222 {
223 }
224 template <class ListNode> void
225 List<ListNode>::Insert (ListNode *aNode)
226 {
227 if (!aNode)
228 return;
229 aNode->next = (ListNode *) InterlockedExchangePointer (&head, aNode);
230 }
231 template <class ListNode> ListNode *
232 List<ListNode>::Remove ( ListNode *aNode)
233 {
234 if (!aNode)
235 return NULL;
236 if (!head)
237 return NULL;
238 if (aNode == head)
239 return Pop ();
240 ListNode *resultPrev = head;
241 while (resultPrev && resultPrev->next && !(aNode == resultPrev->next))
242 resultPrev = resultPrev->next;
243 if (resultPrev)
244 return (ListNode *)InterlockedExchangePointer (&resultPrev->next, resultPrev->next->next);
245 return NULL;
246 }
247 template <class ListNode> ListNode *
248 List<ListNode>::Pop ()
249 {
250 return (ListNode *) InterlockedExchangePointer (&head, head->next);
251 }
252 /* poor mans generic programming. */
253 template <class ListNode> void
254 List<ListNode>::forEach (void (*callback)(ListNode *))
255 {
256 ListNode *aNode = head;
257 while (aNode)
258 {
259 callback (aNode);
260 aNode = aNode->next;
261 }
262 }
263
264 class pthread_attr:public verifyable_object
265 {
266 public:
267 static bool isGoodObject(pthread_attr_t const *);
268 int joinable;
269 int contentionscope;
270 int inheritsched;
271 struct sched_param schedparam;
272 size_t stacksize;
273
274 pthread_attr ();
275 ~pthread_attr ();
276 };
277
278 class pthread_mutexattr:public verifyable_object
279 {
280 public:
281 static bool isGoodObject(pthread_mutexattr_t const *);
282 int pshared;
283 int mutextype;
284 pthread_mutexattr ();
285 ~pthread_mutexattr ();
286 };
287
288 class pthread_mutex:public verifyable_object
289 {
290 public:
291 static bool isGoodObject(pthread_mutex_t const *);
292 static bool isGoodInitializer(pthread_mutex_t const *);
293 static bool isGoodInitializerOrObject(pthread_mutex_t const *);
294 CRITICAL_SECTION criticalsection;
295 HANDLE win32_obj_id;
296 LONG condwaits;
297 int pshared;
298 class pthread_mutex * next;
299
300 int Lock ();
301 int TryLock ();
302 int UnLock ();
303 void fixup_after_fork ();
304
305 pthread_mutex (pthread_mutexattr * = NULL);
306 pthread_mutex (pthread_mutex_t *, pthread_mutexattr *);
307 ~pthread_mutex ();
308 };
309
310 class pthread:public verifyable_object
311 {
312 public:
313 HANDLE win32_obj_id;
314 class pthread_attr attr;
315 void *(*function) (void *);
316 void *arg;
317 void *return_ptr;
318 bool suspended;
319 int cancelstate, canceltype;
320 HANDLE cancel_event;
321 pthread_t joiner;
322 // int joinable;
323
324 /* signal handling */
325 struct sigaction *sigs;
326 sigset_t *sigmask;
327 LONG *sigtodo;
328 virtual void create (void *(*)(void *), pthread_attr *, void *);
329
330 pthread ();
331 virtual ~pthread ();
332
333 static void initMainThread(pthread *, HANDLE);
334 static bool isGoodObject(pthread_t const *);
335 static void atforkprepare();
336 static void atforkparent();
337 static void atforkchild();
338
339 /* API calls */
340 static int cancel (pthread_t);
341 static int join (pthread_t * thread, void **return_val);
342 static int detach (pthread_t * thread);
343 static int create (pthread_t * thread, const pthread_attr_t * attr,
344 void *(*start_routine) (void *), void *arg);
345 static int once (pthread_once_t *, void (*)(void));
346 static int atfork(void (*)(void), void (*)(void), void (*)(void));
347 static int suspend (pthread_t * thread);
348 static int resume (pthread_t * thread);
349
350 virtual void exit (void *value_ptr);
351
352 virtual int cancel ();
353
354 virtual void testcancel ();
355 static void static_cancel_self ();
356
357 virtual int setcancelstate (int state, int *oldstate);
358 virtual int setcanceltype (int type, int *oldtype);
359
360 virtual void push_cleanup_handler (__pthread_cleanup_handler *handler);
361 virtual void pop_cleanup_handler (int const execute);
362
363 static pthread* self ();
364 static void *thread_init_wrapper (void *);
365
366 virtual unsigned long getsequence_np();
367
368 private:
369 DWORD thread_id;
370 __pthread_cleanup_handler *cleanup_stack;
371 pthread_mutex mutex;
372
373 void pop_all_cleanup_handlers (void);
374 void precreate (pthread_attr *);
375 void postcreate ();
376 void setThreadIdtoCurrent();
377 static void setTlsSelfPointer(pthread *);
378 void cancel_self ();
379 DWORD getThreadId ();
380 };
381
382 class pthreadNull : public pthread
383 {
384 public:
385 static pthread *getNullpthread();
386 ~pthreadNull();
387
388 /* From pthread These should never get called
389 * as the ojbect is not verifyable
390 */
391 void create (void *(*)(void *), pthread_attr *, void *);
392 void exit (void *value_ptr);
393 int cancel ();
394 void testcancel ();
395 int setcancelstate (int state, int *oldstate);
396 int setcanceltype (int type, int *oldtype);
397 void push_cleanup_handler (__pthread_cleanup_handler *handler);
398 void pop_cleanup_handler (int const execute);
399 unsigned long getsequence_np();
400
401 private:
402 pthreadNull ();
403 static pthreadNull _instance;
404 };
405
406 class pthread_condattr:public verifyable_object
407 {
408 public:
409 static bool isGoodObject(pthread_condattr_t const *);
410 int shared;
411
412 pthread_condattr ();
413 ~pthread_condattr ();
414 };
415
416 class pthread_cond:public verifyable_object
417 {
418 public:
419 static bool isGoodObject(pthread_cond_t const *);
420 static bool isGoodInitializer(pthread_cond_t const *);
421 static bool isGoodInitializerOrObject(pthread_cond_t const *);
422 int shared;
423 LONG waiting;
424 LONG ExitingWait;
425 pthread_mutex *mutex;
426 /* to allow atomic behaviour for cond_broadcast */
427 pthread_mutex_t cond_access;
428 HANDLE win32_obj_id;
429 class pthread_cond * next;
430 int TimedWait (DWORD dwMilliseconds);
431 void BroadCast ();
432 void Signal ();
433 void fixup_after_fork ();
434
435 pthread_cond (pthread_condattr *);
436 ~pthread_cond ();
437 };
438
439 class pthread_once
440 {
441 public:
442 pthread_mutex_t mutex;
443 int state;
444 };
445
446 /* shouldn't be here */
447 class semaphore:public verifyable_object
448 {
449 public:
450 static bool isGoodObject(sem_t const *);
451 /* API calls */
452 static int init (sem_t * sem, int pshared, unsigned int value);
453 static int destroy (sem_t * sem);
454 static int wait (sem_t * sem);
455 static int trywait (sem_t * sem);
456 static int post (sem_t * sem);
457
458 HANDLE win32_obj_id;
459 class semaphore * next;
460 int shared;
461 long currentvalue;
462 void Wait ();
463 void Post ();
464 int TryWait ();
465 void fixup_after_fork ();
466
467 semaphore (int, unsigned int);
468 ~semaphore ();
469 };
470
471 class callback
472 {
473 public:
474 void (*cb)(void);
475 class callback * next;
476 };
477
478 class MTinterface
479 {
480 public:
481 // General
482 DWORD reent_index;
483 DWORD thread_self_dwTlsIndex;
484 /* we may get 0 for the Tls index.. grrr */
485 int indexallocated;
486 int concurrency;
487 long int threadcount;
488
489 // Used for main thread data, and sigproc thread
490 struct __reent_t reents;
491 struct _winsup_t winsup_reent;
492 pthread mainthread;
493
494 callback *pthread_prepare;
495 callback *pthread_child;
496 callback *pthread_parent;
497
498 // lists of pthread objects. USE THREADSAFE INSERTS AND DELETES.
499 class pthread_mutex * mutexs;
500 class pthread_cond * conds;
501 class semaphore * semaphores;
502
503 void Init (int);
504 void fixup_before_fork (void);
505 void fixup_after_fork (void);
506
507 MTinterface ():reent_index (0), indexallocated (0), threadcount (1)
508 {
509 pthread_prepare = NULL;
510 pthread_child = NULL;
511 pthread_parent = NULL;
512 }
513 };
514
515 extern "C"
516 {
517 int __pthread_attr_init (pthread_attr_t * attr);
518 int __pthread_attr_destroy (pthread_attr_t * attr);
519 int __pthread_attr_setdetachstate (pthread_attr_t *, int);
520 int __pthread_attr_getdetachstate (const pthread_attr_t *, int *);
521 int __pthread_attr_setstacksize (pthread_attr_t * attr, size_t size);
522 int __pthread_attr_getstacksize (const pthread_attr_t * attr, size_t * size);
523
524 int __pthread_attr_getinheritsched (const pthread_attr_t *, int *);
525 int __pthread_attr_getschedparam (const pthread_attr_t *,
526 struct sched_param *);
527 int __pthread_attr_getschedpolicy (const pthread_attr_t *, int *);
528 int __pthread_attr_getscope (const pthread_attr_t *, int *);
529 int __pthread_attr_getstackaddr (const pthread_attr_t *, void **);
530 int __pthread_attr_setinheritsched (pthread_attr_t *, int);
531 int __pthread_attr_setschedparam (pthread_attr_t *,
532 const struct sched_param *);
533 int __pthread_attr_setschedpolicy (pthread_attr_t *, int);
534 int __pthread_attr_setscope (pthread_attr_t *, int);
535 int __pthread_attr_setstackaddr (pthread_attr_t *, void *);
536
537 /* Thread SpecificData */
538 int __pthread_key_create (pthread_key_t * key, void (*destructor) (void *));
539 int __pthread_key_delete (pthread_key_t key);
540 int __pthread_setspecific (pthread_key_t key, const void *value);
541 void *__pthread_getspecific (pthread_key_t key);
542
543 /* Thead synchroniation */
544 int __pthread_cond_destroy (pthread_cond_t * cond);
545 int __pthread_cond_init (pthread_cond_t * cond,
546 const pthread_condattr_t * attr);
547 int __pthread_cond_signal (pthread_cond_t * cond);
548 int __pthread_cond_broadcast (pthread_cond_t * cond);
549 int __pthread_condattr_init (pthread_condattr_t * condattr);
550 int __pthread_condattr_destroy (pthread_condattr_t * condattr);
551 int __pthread_condattr_getpshared (const pthread_condattr_t * attr,
552 int *pshared);
553 int __pthread_condattr_setpshared (pthread_condattr_t * attr, int pshared);
554
555 /* Thread signal */
556 int __pthread_kill (pthread_t thread, int sig);
557 int __pthread_sigmask (int operation, const sigset_t * set,
558 sigset_t * old_set);
559
560 /* ID */
561 int __pthread_equal (pthread_t * t1, pthread_t * t2);
562
563 /* Mutexes */
564 int __pthread_mutex_init (pthread_mutex_t *, const pthread_mutexattr_t *);
565 int __pthread_mutex_lock (pthread_mutex_t *);
566 int __pthread_mutex_trylock (pthread_mutex_t *);
567 int __pthread_mutex_unlock (pthread_mutex_t *);
568 int __pthread_mutex_destroy (pthread_mutex_t *);
569 int __pthread_mutex_setprioceiling (pthread_mutex_t * mutex,
570 int prioceiling, int *old_ceiling);
571 int __pthread_mutex_getprioceiling (const pthread_mutex_t * mutex,
572 int *prioceiling);
573
574
575 int __pthread_mutexattr_destroy (pthread_mutexattr_t *);
576 int __pthread_mutexattr_getprioceiling (const pthread_mutexattr_t *, int *);
577 int __pthread_mutexattr_getprotocol (const pthread_mutexattr_t *, int *);
578 int __pthread_mutexattr_getpshared (const pthread_mutexattr_t *, int *);
579 int __pthread_mutexattr_gettype (const pthread_mutexattr_t *, int *);
580 int __pthread_mutexattr_init (pthread_mutexattr_t *);
581 int __pthread_mutexattr_setprioceiling (pthread_mutexattr_t *, int);
582 int __pthread_mutexattr_setprotocol (pthread_mutexattr_t *, int);
583 int __pthread_mutexattr_setpshared (pthread_mutexattr_t *, int);
584 int __pthread_mutexattr_settype (pthread_mutexattr_t *, int);
585
586
587 /* Scheduling */
588 int __pthread_getconcurrency (void);
589 int __pthread_setconcurrency (int new_level);
590 int __pthread_getschedparam (pthread_t thread, int *policy,
591 struct sched_param *param);
592 int __pthread_setschedparam (pthread_t thread, int policy,
593 const struct sched_param *param);
594
595 };
596 #endif // MT_SAFE
597
598 #endif // _CYGNUS_THREADS_
This page took 0.06327 seconds and 6 git commands to generate.