blob: 5e7fc6ccc1cbe03da004fc45cc9bbb7b0440c5db [file] [log] [blame]
Guido van Rossum34679b71993-01-26 13:33:44 +00001
Guido van Rossum1d5735e1994-08-30 08:27:36 +00002/* 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
Martin v. Löwiscdc44512002-01-12 11:05:12 +00008#include "Python.h"
Guido van Rossum1d5735e1994-08-30 08:27:36 +00009
Matthias Klosea2542be2004-08-16 11:35:51 +000010
11#ifndef _POSIX_THREADS
12/* This means pthreads are not implemented in libc headers, hence the macro
13 not present in unistd.h. But they still can be implemented as an external
14 library (e.g. gnu pth in pthread emulation) */
15# ifdef HAVE_PTHREAD_H
16# include <pthread.h> /* _POSIX_THREADS */
17# endif
18#endif
19
Guido van Rossum2571cc81999-04-07 16:07:23 +000020#ifndef DONT_HAVE_STDIO_H
Guido van Rossum1d5735e1994-08-30 08:27:36 +000021#include <stdio.h>
Guido van Rossum2571cc81999-04-07 16:07:23 +000022#endif
Guido van Rossum1d5735e1994-08-30 08:27:36 +000023
Guido van Rossum1d5735e1994-08-30 08:27:36 +000024#include <stdlib.h>
Guido van Rossum1d5735e1994-08-30 08:27:36 +000025
Guido van Rossumd11bfdd1997-04-29 21:48:34 +000026#ifdef __sgi
27#ifndef HAVE_PTHREAD_H /* XXX Need to check in configure.in */
28#undef _POSIX_THREADS
29#endif
30#endif
31
Guido van Rossum49b56061998-10-01 20:42:43 +000032#include "pythread.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +000033
Guido van Rossum1d5735e1994-08-30 08:27:36 +000034#ifndef _POSIX_THREADS
35
Guido van Rossum1984f1e1992-08-04 12:41:02 +000036#ifdef __sgi
Guido van Rossum1d5735e1994-08-30 08:27:36 +000037#define SGI_THREADS
Guido van Rossum1984f1e1992-08-04 12:41:02 +000038#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +000039
Guido van Rossum1d5735e1994-08-30 08:27:36 +000040#ifdef HAVE_THREAD_H
41#define SOLARIS_THREADS
42#endif
Guido van Rossum1984f1e1992-08-04 12:41:02 +000043
Guido van Rossum1d5735e1994-08-30 08:27:36 +000044#if defined(sun) && !defined(SOLARIS_THREADS)
45#define SUN_LWP
46#endif
47
Guido van Rossum539c6622005-09-14 17:49:54 +000048/* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then
49 enough of the Posix threads package is implimented to support python
50 threads.
51
52 This is valid for HP-UX 11.23 running on an ia64 system. If needed, add
53 a check of __ia64 to verify that we're running on a ia64 system instead
54 of a pa-risc system.
55*/
56#ifdef __hpux
57#ifdef _SC_THREADS
58#define _POSIX_THREADS
59#endif
60#endif
61
Sjoerd Mullender66bca321993-12-03 16:54:45 +000062#endif /* _POSIX_THREADS */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000063
Guido van Rossum1984f1e1992-08-04 12:41:02 +000064
Guido van Rossum408027e1996-12-30 16:17:54 +000065#ifdef Py_DEBUG
Guido van Rossum1d5735e1994-08-30 08:27:36 +000066static int thread_debug = 0;
Jeremy Hyltonbd232892002-06-25 19:26:34 +000067#define dprintf(args) (void)((thread_debug & 1) && printf args)
Guido van Rossum1d5735e1994-08-30 08:27:36 +000068#define d2printf(args) ((thread_debug & 8) && printf args)
69#else
70#define dprintf(args)
71#define d2printf(args)
72#endif
73
Guido van Rossum1984f1e1992-08-04 12:41:02 +000074static int initialized;
75
Thomas Wouters8ec68fd2000-07-24 14:39:50 +000076static void PyThread__init_thread(void); /* Forward */
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +000077
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000078void PyThread_init_thread(void)
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +000079{
Guido van Rossum408027e1996-12-30 16:17:54 +000080#ifdef Py_DEBUG
Sjoerd Mullender66bca321993-12-03 16:54:45 +000081 char *p = getenv("THREADDEBUG");
82
83 if (p) {
84 if (*p)
85 thread_debug = atoi(p);
86 else
87 thread_debug = 1;
88 }
Guido van Rossum408027e1996-12-30 16:17:54 +000089#endif /* Py_DEBUG */
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +000090 if (initialized)
91 return;
92 initialized = 1;
Guido van Rossum65d5b571998-12-21 19:32:43 +000093 dprintf(("PyThread_init_thread called\n"));
94 PyThread__init_thread();
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +000095}
96
Guido van Rossum1d5735e1994-08-30 08:27:36 +000097#ifdef SGI_THREADS
98#include "thread_sgi.h"
Sjoerd Mullender66bca321993-12-03 16:54:45 +000099#endif
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000100
101#ifdef SOLARIS_THREADS
102#include "thread_solaris.h"
103#endif
104
105#ifdef SUN_LWP
106#include "thread_lwp.h"
107#endif
108
Guido van Rossum9e8181b2000-09-19 00:46:46 +0000109#ifdef HAVE_PTH
Guido van Rossum07bd90e2000-05-08 13:41:38 +0000110#include "thread_pth.h"
Martin v. Löwis70849f82003-09-20 11:13:36 +0000111#undef _POSIX_THREADS
Guido van Rossum9e8181b2000-09-19 00:46:46 +0000112#endif
113
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000114#ifdef _POSIX_THREADS
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000115#include "thread_pthread.h"
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000116#endif
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000117
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000118#ifdef C_THREADS
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000119#include "thread_cthread.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000120#endif
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000121
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000122#ifdef NT_THREADS
123#include "thread_nt.h"
124#endif
125
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000126#ifdef OS2_THREADS
127#include "thread_os2.h"
128#endif
129
Guido van Rossum1a8791e1998-08-04 22:46:29 +0000130#ifdef BEOS_THREADS
131#include "thread_beos.h"
132#endif
133
Guido van Rossum2571cc81999-04-07 16:07:23 +0000134#ifdef WINCE_THREADS
135#include "thread_wince.h"
136#endif
137
Martin v. Löwis7d1cd692002-03-09 12:10:54 +0000138#ifdef PLAN9_THREADS
139#include "thread_plan9.h"
140#endif
141
Martin v. Löwisf90ae202002-06-11 06:22:31 +0000142#ifdef ATHEOS_THREADS
143#include "thread_atheos.h"
144#endif
145
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000146/*
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000147#ifdef FOOBAR_THREADS
148#include "thread_foobar.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000149#endif
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000150*/
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000151
152#ifndef Py_HAVE_NATIVE_TLS
153/* If the platform has not supplied a platform specific
154 TLS implementation, provide our own.
155
156 This code stolen from "thread_sgi.h", where it was the only
157 implementation of an existing Python TLS API.
158*/
Tim Petersfda787f2004-10-09 22:33:09 +0000159/* ------------------------------------------------------------------------
160Per-thread data ("key") support.
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000161
Tim Petersfda787f2004-10-09 22:33:09 +0000162Use PyThread_create_key() to create a new key. This is typically shared
163across threads.
164
165Use PyThread_set_key_value(thekey, value) to associate void* value with
166thekey in the current thread. Each thread has a distinct mapping of thekey
167to a void* value. Caution: if the current thread already has a mapping
168for thekey, value is ignored.
169
170Use PyThread_get_key_value(thekey) to retrieve the void* value associated
171with thekey in the current thread. This returns NULL if no value is
172associated with thekey in the current thread.
173
174Use PyThread_delete_key_value(thekey) to forget the current thread's associated
175value for thekey. PyThread_delete_key(thekey) forgets the values associated
176with thekey across *all* threads.
177
178While some of these functions have error-return values, none set any
179Python exception.
180
181None of the functions does memory management on behalf of the void* values.
182You need to allocate and deallocate them yourself. If the void* values
183happen to be PyObject*, these functions don't do refcount operations on
184them either.
185
186The GIL does not need to be held when calling these functions; they supply
187their own locking. This isn't true of PyThread_create_key(), though (see
188next paragraph).
189
190There's a hidden assumption that PyThread_create_key() will be called before
191any of the other functions are called. There's also a hidden assumption
192that calls to PyThread_create_key() are serialized externally.
193------------------------------------------------------------------------ */
194
195/* A singly-linked list of struct key objects remembers all the key->value
196 * associations. File static keyhead heads the list. keymutex is used
197 * to enforce exclusion internally.
198 */
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000199struct key {
Tim Petersfda787f2004-10-09 22:33:09 +0000200 /* Next record in the list, or NULL if this is the last record. */
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000201 struct key *next;
Tim Petersfda787f2004-10-09 22:33:09 +0000202
203 /* The thread id, according to PyThread_get_thread_ident(). */
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000204 long id;
Tim Petersfda787f2004-10-09 22:33:09 +0000205
206 /* The key and its associated value. */
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000207 int key;
208 void *value;
209};
210
211static struct key *keyhead = NULL;
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000212static PyThread_type_lock keymutex = NULL;
Tim Petersfda787f2004-10-09 22:33:09 +0000213static int nkeys = 0; /* PyThread_create_key() hands out nkeys+1 next */
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000214
Tim Petersfda787f2004-10-09 22:33:09 +0000215/* Internal helper.
216 * If the current thread has a mapping for key, the appropriate struct key*
217 * is returned. NB: value is ignored in this case!
218 * If there is no mapping for key in the current thread, then:
219 * If value is NULL, NULL is returned.
220 * Else a mapping of key to value is created for the current thread,
221 * and a pointer to a new struct key* is returned; except that if
222 * malloc() can't find room for a new struct key*, NULL is returned.
223 * So when value==NULL, this acts like a pure lookup routine, and when
224 * value!=NULL, this acts like dict.setdefault(), returning an existing
225 * mapping if one exists, else creating a new mapping.
Tim Peters263091e2004-10-10 01:58:44 +0000226 *
227 * Caution: this used to be too clever, trying to hold keymutex only
228 * around the "p->next = keyhead; keyhead = p" pair. That allowed
229 * another thread to mutate the list, via key deletion, concurrent with
230 * find_key() crawling over the list. Hilarity ensued. For example, when
231 * the for-loop here does "p = p->next", p could end up pointing at a
232 * record that PyThread_delete_key_value() was concurrently free()'ing.
233 * That could lead to anything, from failing to find a key that exists, to
234 * segfaults. Now we lock the whole routine.
Tim Petersfda787f2004-10-09 22:33:09 +0000235 */
Tim Peters19717fa2004-10-09 17:38:29 +0000236static struct key *
237find_key(int key, void *value)
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000238{
239 struct key *p;
240 long id = PyThread_get_thread_ident();
Tim Petersfda787f2004-10-09 22:33:09 +0000241
Tim Peters263091e2004-10-10 01:58:44 +0000242 PyThread_acquire_lock(keymutex, 1);
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000243 for (p = keyhead; p != NULL; p = p->next) {
244 if (p->id == id && p->key == key)
Tim Peters263091e2004-10-10 01:58:44 +0000245 goto Done;
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000246 }
Tim Peters263091e2004-10-10 01:58:44 +0000247 if (value == NULL) {
248 assert(p == NULL);
249 goto Done;
250 }
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000251 p = (struct key *)malloc(sizeof(struct key));
252 if (p != NULL) {
253 p->id = id;
254 p->key = key;
255 p->value = value;
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000256 p->next = keyhead;
257 keyhead = p;
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000258 }
Tim Peters263091e2004-10-10 01:58:44 +0000259 Done:
260 PyThread_release_lock(keymutex);
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000261 return p;
262}
263
Tim Petersfda787f2004-10-09 22:33:09 +0000264/* Return a new key. This must be called before any other functions in
265 * this family, and callers must arrange to serialize calls to this
266 * function. No violations are detected.
267 */
Tim Peters19717fa2004-10-09 17:38:29 +0000268int
269PyThread_create_key(void)
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000270{
Tim Petersfda787f2004-10-09 22:33:09 +0000271 /* All parts of this function are wrong if it's called by multiple
272 * threads simultaneously.
273 */
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000274 if (keymutex == NULL)
275 keymutex = PyThread_allocate_lock();
276 return ++nkeys;
277}
278
Tim Petersfda787f2004-10-09 22:33:09 +0000279/* Forget the associations for key across *all* threads. */
Tim Peters19717fa2004-10-09 17:38:29 +0000280void
281PyThread_delete_key(int key)
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000282{
283 struct key *p, **q;
Tim Petersfda787f2004-10-09 22:33:09 +0000284
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000285 PyThread_acquire_lock(keymutex, 1);
286 q = &keyhead;
287 while ((p = *q) != NULL) {
288 if (p->key == key) {
289 *q = p->next;
290 free((void *)p);
291 /* NB This does *not* free p->value! */
292 }
293 else
294 q = &p->next;
295 }
296 PyThread_release_lock(keymutex);
297}
298
Tim Petersfda787f2004-10-09 22:33:09 +0000299/* Confusing: If the current thread has an association for key,
300 * value is ignored, and 0 is returned. Else an attempt is made to create
301 * an association of key to value for the current thread. 0 is returned
302 * if that succeeds, but -1 is returned if there's not enough memory
303 * to create the association. value must not be NULL.
304 */
Tim Peters19717fa2004-10-09 17:38:29 +0000305int
306PyThread_set_key_value(int key, void *value)
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000307{
Tim Petersfda787f2004-10-09 22:33:09 +0000308 struct key *p;
309
310 assert(value != NULL);
311 p = find_key(key, value);
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000312 if (p == NULL)
313 return -1;
314 else
315 return 0;
316}
317
Tim Petersfda787f2004-10-09 22:33:09 +0000318/* Retrieve the value associated with key in the current thread, or NULL
319 * if the current thread doesn't have an association for key.
320 */
Tim Peters19717fa2004-10-09 17:38:29 +0000321void *
322PyThread_get_key_value(int key)
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000323{
324 struct key *p = find_key(key, NULL);
Tim Petersfda787f2004-10-09 22:33:09 +0000325
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000326 if (p == NULL)
327 return NULL;
328 else
329 return p->value;
330}
331
Tim Petersfda787f2004-10-09 22:33:09 +0000332/* Forget the current thread's association for key, if any. */
Tim Peters19717fa2004-10-09 17:38:29 +0000333void
334PyThread_delete_key_value(int key)
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000335{
336 long id = PyThread_get_thread_ident();
337 struct key *p, **q;
Tim Petersfda787f2004-10-09 22:33:09 +0000338
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000339 PyThread_acquire_lock(keymutex, 1);
340 q = &keyhead;
341 while ((p = *q) != NULL) {
342 if (p->key == key && p->id == id) {
343 *q = p->next;
344 free((void *)p);
345 /* NB This does *not* free p->value! */
346 break;
347 }
348 else
349 q = &p->next;
350 }
351 PyThread_release_lock(keymutex);
352}
353
354#endif /* Py_HAVE_NATIVE_TLS */