1
2 /* Thread package.
3 This is intended to be usable independently from Python.
4 The implementation for system foobar is in a file thread_foobar.h
5 which is included by this file dependent on config settings.
6 Stuff shared by all thread_*.h files is collected here. */
7
8 #include "Python.h"
9
10 #ifndef _POSIX_THREADS
11 /* This means pthreads are not implemented in libc headers, hence the macro
12 not present in unistd.h. But they still can be implemented as an external
13 library (e.g. gnu pth in pthread emulation) */
14 # ifdef HAVE_PTHREAD_H
15 # include <pthread.h> /* _POSIX_THREADS */
16 # endif
17 #endif
18
19 #ifndef DONT_HAVE_STDIO_H
20 #include <stdio.h>
21 #endif
22
23 #include <stdlib.h>
24
25 #include "pythread.h"
26
27 #ifndef _POSIX_THREADS
28
29 /* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then
30 enough of the Posix threads package is implemented to support python
31 threads.
32
33 This is valid for HP-UX 11.23 running on an ia64 system. If needed, add
34 a check of __ia64 to verify that we're running on an ia64 system instead
35 of a pa-risc system.
36 */
37 #ifdef __hpux
38 #ifdef _SC_THREADS
39 #define _POSIX_THREADS
40 #endif
41 #endif
42
43 #endif /* _POSIX_THREADS */
44
45
46 #ifdef Py_DEBUG
47 static int thread_debug = 0;
48 #define dprintf(args) (void)((thread_debug & 1) && printf args)
49 #define d2printf(args) ((thread_debug & 8) && printf args)
50 #else
51 #define dprintf(args)
52 #define d2printf(args)
53 #endif
54
55 static int initialized;
56
57 static void PyThread__init_thread(void); /* Forward */
58
59 void
PyThread_init_thread(void)60 PyThread_init_thread(void)
61 {
62 #ifdef Py_DEBUG
63 char *p = Py_GETENV("PYTHONTHREADDEBUG");
64
65 if (p) {
66 if (*p)
67 thread_debug = atoi(p);
68 else
69 thread_debug = 1;
70 }
71 #endif /* Py_DEBUG */
72 if (initialized)
73 return;
74 initialized = 1;
75 dprintf(("PyThread_init_thread called\n"));
76 PyThread__init_thread();
77 }
78
79 /* Support for runtime thread stack size tuning.
80 A value of 0 means using the platform's default stack size
81 or the size specified by the THREAD_STACK_SIZE macro. */
82 static size_t _pythread_stacksize = 0;
83
84 #ifdef _POSIX_THREADS
85 #define PYTHREAD_NAME "pthread"
86 #include "thread_pthread.h"
87 #endif
88
89 #ifdef NT_THREADS
90 #define PYTHREAD_NAME "nt"
91 #include "thread_nt.h"
92 #endif
93
94
95 /*
96 #ifdef FOOBAR_THREADS
97 #include "thread_foobar.h"
98 #endif
99 */
100
101 /* return the current thread stack size */
102 size_t
PyThread_get_stacksize(void)103 PyThread_get_stacksize(void)
104 {
105 return _pythread_stacksize;
106 }
107
108 /* Only platforms defining a THREAD_SET_STACKSIZE() macro
109 in thread_<platform>.h support changing the stack size.
110 Return 0 if stack size is valid,
111 -1 if stack size value is invalid,
112 -2 if setting stack size is not supported. */
113 int
PyThread_set_stacksize(size_t size)114 PyThread_set_stacksize(size_t size)
115 {
116 #if defined(THREAD_SET_STACKSIZE)
117 return THREAD_SET_STACKSIZE(size);
118 #else
119 return -2;
120 #endif
121 }
122
123 #ifndef Py_HAVE_NATIVE_TLS
124 /* If the platform has not supplied a platform specific
125 TLS implementation, provide our own.
126
127 This code stolen from "thread_sgi.h", where it was the only
128 implementation of an existing Python TLS API.
129 */
130 /* ------------------------------------------------------------------------
131 Per-thread data ("key") support.
132
133 Use PyThread_create_key() to create a new key. This is typically shared
134 across threads.
135
136 Use PyThread_set_key_value(thekey, value) to associate void* value with
137 thekey in the current thread. Each thread has a distinct mapping of thekey
138 to a void* value. Caution: if the current thread already has a mapping
139 for thekey, value is ignored.
140
141 Use PyThread_get_key_value(thekey) to retrieve the void* value associated
142 with thekey in the current thread. This returns NULL if no value is
143 associated with thekey in the current thread.
144
145 Use PyThread_delete_key_value(thekey) to forget the current thread's associated
146 value for thekey. PyThread_delete_key(thekey) forgets the values associated
147 with thekey across *all* threads.
148
149 While some of these functions have error-return values, none set any
150 Python exception.
151
152 None of the functions does memory management on behalf of the void* values.
153 You need to allocate and deallocate them yourself. If the void* values
154 happen to be PyObject*, these functions don't do refcount operations on
155 them either.
156
157 The GIL does not need to be held when calling these functions; they supply
158 their own locking. This isn't true of PyThread_create_key(), though (see
159 next paragraph).
160
161 There's a hidden assumption that PyThread_create_key() will be called before
162 any of the other functions are called. There's also a hidden assumption
163 that calls to PyThread_create_key() are serialized externally.
164 ------------------------------------------------------------------------ */
165
166 /* A singly-linked list of struct key objects remembers all the key->value
167 * associations. File static keyhead heads the list. keymutex is used
168 * to enforce exclusion internally.
169 */
170 struct key {
171 /* Next record in the list, or NULL if this is the last record. */
172 struct key *next;
173
174 /* The thread id, according to PyThread_get_thread_ident(). */
175 long id;
176
177 /* The key and its associated value. */
178 int key;
179 void *value;
180 };
181
182 static struct key *keyhead = NULL;
183 static PyThread_type_lock keymutex = NULL;
184 static int nkeys = 0; /* PyThread_create_key() hands out nkeys+1 next */
185
186 /* Internal helper.
187 * If the current thread has a mapping for key, the appropriate struct key*
188 * is returned. NB: value is ignored in this case!
189 * If there is no mapping for key in the current thread, then:
190 * If value is NULL, NULL is returned.
191 * Else a mapping of key to value is created for the current thread,
192 * and a pointer to a new struct key* is returned; except that if
193 * malloc() can't find room for a new struct key*, NULL is returned.
194 * So when value==NULL, this acts like a pure lookup routine, and when
195 * value!=NULL, this acts like dict.setdefault(), returning an existing
196 * mapping if one exists, else creating a new mapping.
197 *
198 * Caution: this used to be too clever, trying to hold keymutex only
199 * around the "p->next = keyhead; keyhead = p" pair. That allowed
200 * another thread to mutate the list, via key deletion, concurrent with
201 * find_key() crawling over the list. Hilarity ensued. For example, when
202 * the for-loop here does "p = p->next", p could end up pointing at a
203 * record that PyThread_delete_key_value() was concurrently free()'ing.
204 * That could lead to anything, from failing to find a key that exists, to
205 * segfaults. Now we lock the whole routine.
206 */
207 static struct key *
find_key(int set_value,int key,void * value)208 find_key(int set_value, int key, void *value)
209 {
210 struct key *p, *prev_p;
211 long id = PyThread_get_thread_ident();
212
213 if (!keymutex)
214 return NULL;
215 PyThread_acquire_lock(keymutex, 1);
216 prev_p = NULL;
217 for (p = keyhead; p != NULL; p = p->next) {
218 if (p->id == id && p->key == key) {
219 if (set_value)
220 p->value = value;
221 goto Done;
222 }
223 /* Sanity check. These states should never happen but if
224 * they do we must abort. Otherwise we'll end up spinning
225 * in a tight loop with the lock held. A similar check is done
226 * in pystate.c tstate_delete_common(). */
227 if (p == prev_p)
228 Py_FatalError("tls find_key: small circular list(!)");
229 prev_p = p;
230 if (p->next == keyhead)
231 Py_FatalError("tls find_key: circular list(!)");
232 }
233 if (!set_value && value == NULL) {
234 assert(p == NULL);
235 goto Done;
236 }
237 p = (struct key *)PyMem_RawMalloc(sizeof(struct key));
238 if (p != NULL) {
239 p->id = id;
240 p->key = key;
241 p->value = value;
242 p->next = keyhead;
243 keyhead = p;
244 }
245 Done:
246 PyThread_release_lock(keymutex);
247 return p;
248 }
249
250 /* Return a new key. This must be called before any other functions in
251 * this family, and callers must arrange to serialize calls to this
252 * function. No violations are detected.
253 */
254 int
PyThread_create_key(void)255 PyThread_create_key(void)
256 {
257 /* All parts of this function are wrong if it's called by multiple
258 * threads simultaneously.
259 */
260 if (keymutex == NULL)
261 keymutex = PyThread_allocate_lock();
262 return ++nkeys;
263 }
264
265 /* Forget the associations for key across *all* threads. */
266 void
PyThread_delete_key(int key)267 PyThread_delete_key(int key)
268 {
269 struct key *p, **q;
270
271 PyThread_acquire_lock(keymutex, 1);
272 q = &keyhead;
273 while ((p = *q) != NULL) {
274 if (p->key == key) {
275 *q = p->next;
276 PyMem_RawFree((void *)p);
277 /* NB This does *not* free p->value! */
278 }
279 else
280 q = &p->next;
281 }
282 PyThread_release_lock(keymutex);
283 }
284
285 int
PyThread_set_key_value(int key,void * value)286 PyThread_set_key_value(int key, void *value)
287 {
288 struct key *p;
289
290 p = find_key(1, key, value);
291 if (p == NULL)
292 return -1;
293 else
294 return 0;
295 }
296
297 /* Retrieve the value associated with key in the current thread, or NULL
298 * if the current thread doesn't have an association for key.
299 */
300 void *
PyThread_get_key_value(int key)301 PyThread_get_key_value(int key)
302 {
303 struct key *p = find_key(0, key, NULL);
304
305 if (p == NULL)
306 return NULL;
307 else
308 return p->value;
309 }
310
311 /* Forget the current thread's association for key, if any. */
312 void
PyThread_delete_key_value(int key)313 PyThread_delete_key_value(int key)
314 {
315 long id = PyThread_get_thread_ident();
316 struct key *p, **q;
317
318 PyThread_acquire_lock(keymutex, 1);
319 q = &keyhead;
320 while ((p = *q) != NULL) {
321 if (p->key == key && p->id == id) {
322 *q = p->next;
323 PyMem_RawFree((void *)p);
324 /* NB This does *not* free p->value! */
325 break;
326 }
327 else
328 q = &p->next;
329 }
330 PyThread_release_lock(keymutex);
331 }
332
333 /* Forget everything not associated with the current thread id.
334 * This function is called from PyOS_AfterFork(). It is necessary
335 * because other thread ids which were in use at the time of the fork
336 * may be reused for new threads created in the forked process.
337 */
338 void
PyThread_ReInitTLS(void)339 PyThread_ReInitTLS(void)
340 {
341 long id = PyThread_get_thread_ident();
342 struct key *p, **q;
343
344 if (!keymutex)
345 return;
346
347 /* As with interpreter_lock in PyEval_ReInitThreads()
348 we just create a new lock without freeing the old one */
349 keymutex = PyThread_allocate_lock();
350
351 /* Delete all keys which do not match the current thread id */
352 q = &keyhead;
353 while ((p = *q) != NULL) {
354 if (p->id != id) {
355 *q = p->next;
356 PyMem_RawFree((void *)p);
357 /* NB This does *not* free p->value! */
358 }
359 else
360 q = &p->next;
361 }
362 }
363
364 #endif /* Py_HAVE_NATIVE_TLS */
365
366 PyDoc_STRVAR(threadinfo__doc__,
367 "sys.thread_info\n\
368 \n\
369 A struct sequence holding information about the thread implementation.");
370
371 static PyStructSequence_Field threadinfo_fields[] = {
372 {"name", "name of the thread implementation"},
373 {"lock", "name of the lock implementation"},
374 {"version", "name and version of the thread library"},
375 {0}
376 };
377
378 static PyStructSequence_Desc threadinfo_desc = {
379 "sys.thread_info", /* name */
380 threadinfo__doc__, /* doc */
381 threadinfo_fields, /* fields */
382 3
383 };
384
385 static PyTypeObject ThreadInfoType;
386
387 PyObject*
PyThread_GetInfo(void)388 PyThread_GetInfo(void)
389 {
390 PyObject *threadinfo, *value;
391 int pos = 0;
392 #if (defined(_POSIX_THREADS) && defined(HAVE_CONFSTR) \
393 && defined(_CS_GNU_LIBPTHREAD_VERSION))
394 char buffer[255];
395 int len;
396 #endif
397
398 if (ThreadInfoType.tp_name == 0) {
399 if (PyStructSequence_InitType2(&ThreadInfoType, &threadinfo_desc) < 0)
400 return NULL;
401 }
402
403 threadinfo = PyStructSequence_New(&ThreadInfoType);
404 if (threadinfo == NULL)
405 return NULL;
406
407 value = PyUnicode_FromString(PYTHREAD_NAME);
408 if (value == NULL) {
409 Py_DECREF(threadinfo);
410 return NULL;
411 }
412 PyStructSequence_SET_ITEM(threadinfo, pos++, value);
413
414 #ifdef _POSIX_THREADS
415 #ifdef USE_SEMAPHORES
416 value = PyUnicode_FromString("semaphore");
417 #else
418 value = PyUnicode_FromString("mutex+cond");
419 #endif
420 if (value == NULL) {
421 Py_DECREF(threadinfo);
422 return NULL;
423 }
424 #else
425 Py_INCREF(Py_None);
426 value = Py_None;
427 #endif
428 PyStructSequence_SET_ITEM(threadinfo, pos++, value);
429
430 #if (defined(_POSIX_THREADS) && defined(HAVE_CONFSTR) \
431 && defined(_CS_GNU_LIBPTHREAD_VERSION))
432 value = NULL;
433 len = confstr(_CS_GNU_LIBPTHREAD_VERSION, buffer, sizeof(buffer));
434 if (1 < len && (size_t)len < sizeof(buffer)) {
435 value = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
436 if (value == NULL)
437 PyErr_Clear();
438 }
439 if (value == NULL)
440 #endif
441 {
442 Py_INCREF(Py_None);
443 value = Py_None;
444 }
445 PyStructSequence_SET_ITEM(threadinfo, pos++, value);
446 return threadinfo;
447 }
448