]>
Commit | Line | Data |
---|---|---|
2d1d1eb1 | 1 | /* cygtls.cc |
281e4194 | 2 | |
281e4194 CF |
3 | This software is a copyrighted work licensed under the terms of the |
4 | Cygwin license. Please consult the file "CYGWIN_LICENSE" for | |
5 | details. */ | |
6 | ||
7 | #include "winsup.h" | |
893ac8e0 | 8 | #define USE_SYS_TYPES_FD_SET |
281e4194 | 9 | #include "cygtls.h" |
281e4194 | 10 | #include <syslog.h> |
2be50cac | 11 | #include <stdlib.h> |
2d1d1eb1 CF |
12 | #include "path.h" |
13 | #include "fhandler.h" | |
14 | #include "dtable.h" | |
782ef536 | 15 | #include "create_posix_thread.h" |
2d1d1eb1 | 16 | #include "cygheap.h" |
f6936c48 | 17 | #include "sigproc.h" |
98a97ac6 | 18 | #include "exception.h" |
2d1d1eb1 | 19 | |
281e4194 CF |
20 | /* Two calls to get the stack right... */ |
21 | void | |
e431827c | 22 | _cygtls::call (DWORD (*func) (void *, void *), void *arg) |
281e4194 | 23 | { |
d4fa3b4a | 24 | char buf[__CYGTLS_PADSIZE__]; |
98a97ac6 CF |
25 | /* Initialize this thread's ability to respond to things like |
26 | SIGSEGV or SIGFPE. */ | |
27 | exception protect; | |
38229bcd | 28 | _my_tls.call2 (func, arg, buf); |
281e4194 CF |
29 | } |
30 | ||
31 | void | |
e431827c | 32 | _cygtls::call2 (DWORD (*func) (void *, void *), void *arg, void *buf) |
281e4194 | 33 | { |
9d2eff66 CV |
34 | /* If func is pthread_wrapper, the final stack hasn't been set up yet. |
35 | This only happens in pthread_wrapper itself. Thus it doesn't make | |
36 | sense to call init_thread or perform BLODA detection. pthread_wrapper | |
37 | eventually calls init_thread by itself. */ | |
38 | if ((void *) func != (void *) pthread_wrapper) | |
cb34fffe | 39 | init_thread (buf, func); |
07a6b9dd | 40 | |
2d1d1eb1 | 41 | DWORD res = func (arg, buf); |
38229bcd | 42 | remove (INFINITE); |
a2b6c065 CF |
43 | /* Don't call ExitThread on the main thread since we may have been |
44 | dynamically loaded. */ | |
2346864a CF |
45 | if ((void *) func != (void *) dll_crt0_1 |
46 | && (void *) func != (void *) dll_dllcrt0_1) | |
65068ebd | 47 | ExitThread (res); |
281e4194 CF |
48 | } |
49 | ||
50 | void | |
e431827c | 51 | _cygtls::init_thread (void *x, DWORD (*func) (void *, void *)) |
281e4194 CF |
52 | { |
53 | if (x) | |
54 | { | |
562adf78 | 55 | memset (this, 0, sizeof (*this)); |
cd441f06 | 56 | _REENT_INIT_PTR (&local_clib); |
281e4194 | 57 | stackptr = stack; |
22465796 | 58 | altstack.ss_flags = SS_DISABLE; |
f89ce35d | 59 | if (_REENT_CLEANUP(_GLOBAL_REENT)) |
d02421e7 | 60 | local_clib.__cleanup = _cygtls::cleanup_early; |
281e4194 CF |
61 | } |
62 | ||
985d0e68 | 63 | thread_id = GetCurrentThreadId (); |
09b01096 | 64 | initialized = CYGTLS_INITIALIZED; |
281e4194 | 65 | errno_addr = &(local_clib._errno); |
f0968c1e | 66 | locals.cw_timer = NULL; |
63b50391 | 67 | locals.pathbufs.clear (); |
2d1d1eb1 CF |
68 | |
69 | if ((void *) func == (void *) cygthread::stub | |
70 | || (void *) func == (void *) cygthread::simplestub) | |
71 | return; | |
72 | ||
52d2371d | 73 | cygheap->add_tls (this); |
281e4194 CF |
74 | } |
75 | ||
76 | void | |
e431827c CF |
77 | _cygtls::fixup_after_fork () |
78 | { | |
e867f8f1 CF |
79 | if (sig) |
80 | { | |
81 | pop (); | |
82 | sig = 0; | |
83 | } | |
82c925af | 84 | stacklock = spinning = 0; |
962f9a2c | 85 | signal_arrived = NULL; |
023c2582 | 86 | locals.select.sockevt = NULL; |
f0968c1e | 87 | locals.cw_timer = NULL; |
63b50391 | 88 | locals.pathbufs.clear (); |
9863b78e | 89 | wq.thread_ev = NULL; |
e431827c CF |
90 | } |
91 | ||
fe836470 CF |
92 | #define free_local(x) \ |
93 | if (locals.x) \ | |
94 | { \ | |
95 | free (locals.x); \ | |
96 | locals.x = NULL; \ | |
97 | } | |
98 | ||
e431827c CF |
99 | void |
100 | _cygtls::remove (DWORD wait) | |
281e4194 | 101 | { |
9badd94a | 102 | initialized = 0; |
023c2582 | 103 | if (exit_state >= ES_FINAL) |
55b67002 | 104 | return; |
4cf4fd4d | 105 | |
61522196 | 106 | debug_printf ("wait %u", wait); |
a0307f99 | 107 | |
26158dc3 | 108 | HANDLE mutex = cygheap->remove_tls (this); |
9d2eff66 CV |
109 | remove_wq (wait); |
110 | ||
a0307f99 CV |
111 | /* FIXME: Need some sort of atthreadexit function to allow things like |
112 | select to control this themselves. */ | |
113 | ||
cf51db8b | 114 | remove_pending_sigs (); |
962f9a2c CF |
115 | if (signal_arrived) |
116 | { | |
117 | HANDLE h = signal_arrived; | |
118 | signal_arrived = NULL; | |
119 | CloseHandle (h); | |
120 | } | |
121 | ||
a0307f99 | 122 | /* Close handle and free memory used by select. */ |
1d8170bd | 123 | if (locals.select.sockevt) |
42aa06a5 | 124 | { |
a0307f99 CV |
125 | CloseHandle (locals.select.sockevt); |
126 | locals.select.sockevt = NULL; | |
127 | free_local (select.ser_num); | |
128 | free_local (select.w4); | |
42aa06a5 | 129 | } |
a0307f99 CV |
130 | /* Free memory used by network functions. */ |
131 | free_local (ntoa_buf); | |
132 | free_local (protoent_buf); | |
133 | free_local (servent_buf); | |
134 | free_local (hostent_buf); | |
752b16ce | 135 | /* Free temporary TLS path buffers. */ |
5578cc4b | 136 | locals.pathbufs.destroy (); |
78cefca9 CV |
137 | /* Close timer handle. */ |
138 | if (locals.cw_timer) | |
139 | NtClose (locals.cw_timer); | |
26158dc3 CV |
140 | if (mutex) |
141 | { | |
142 | ReleaseMutex (mutex); | |
143 | CloseHandle (mutex); | |
144 | } | |
281e4194 | 145 | } |
12b24439 | 146 | |
44b60f0c MJ |
147 | void |
148 | _cygtls::cleanup_early (struct _reent *) | |
149 | { | |
150 | /* Do nothing */ | |
151 | } | |
152 | ||
12b24439 CV |
153 | void san::leave () |
154 | { | |
155 | /* Restore tls_pathbuf counters in case of error. */ | |
156 | _my_tls.locals.pathbufs._counters = _cnt; | |
60f10c64 | 157 | _my_tls.andreas = _clemente; |
12b24439 | 158 | } |