blob: 3985779c87e92532b15e30ad396090de4f8120d4 [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
Sjoerd Mullender66bca321993-12-03 16:54:45 +000048#endif /* _POSIX_THREADS */
Guido van Rossum1984f1e1992-08-04 12:41:02 +000049
Guido van Rossum1984f1e1992-08-04 12:41:02 +000050
Guido van Rossum408027e1996-12-30 16:17:54 +000051#ifdef Py_DEBUG
Guido van Rossum1d5735e1994-08-30 08:27:36 +000052static int thread_debug = 0;
Jeremy Hyltonbd232892002-06-25 19:26:34 +000053#define dprintf(args) (void)((thread_debug & 1) && printf args)
Guido van Rossum1d5735e1994-08-30 08:27:36 +000054#define d2printf(args) ((thread_debug & 8) && printf args)
55#else
56#define dprintf(args)
57#define d2printf(args)
58#endif
59
Guido van Rossum1984f1e1992-08-04 12:41:02 +000060static int initialized;
61
Thomas Wouters8ec68fd2000-07-24 14:39:50 +000062static void PyThread__init_thread(void); /* Forward */
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +000063
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000064void PyThread_init_thread(void)
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +000065{
Guido van Rossum408027e1996-12-30 16:17:54 +000066#ifdef Py_DEBUG
Sjoerd Mullender66bca321993-12-03 16:54:45 +000067 char *p = getenv("THREADDEBUG");
68
69 if (p) {
70 if (*p)
71 thread_debug = atoi(p);
72 else
73 thread_debug = 1;
74 }
Guido van Rossum408027e1996-12-30 16:17:54 +000075#endif /* Py_DEBUG */
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +000076 if (initialized)
77 return;
78 initialized = 1;
Guido van Rossum65d5b571998-12-21 19:32:43 +000079 dprintf(("PyThread_init_thread called\n"));
80 PyThread__init_thread();
Sjoerd Mullenderaee8bc11992-09-02 11:25:37 +000081}
82
Guido van Rossum1d5735e1994-08-30 08:27:36 +000083#ifdef SGI_THREADS
84#include "thread_sgi.h"
Sjoerd Mullender66bca321993-12-03 16:54:45 +000085#endif
Guido van Rossum1d5735e1994-08-30 08:27:36 +000086
87#ifdef SOLARIS_THREADS
88#include "thread_solaris.h"
89#endif
90
91#ifdef SUN_LWP
92#include "thread_lwp.h"
93#endif
94
Guido van Rossum9e8181b2000-09-19 00:46:46 +000095#ifdef HAVE_PTH
Guido van Rossum07bd90e2000-05-08 13:41:38 +000096#include "thread_pth.h"
Martin v. Löwis70849f82003-09-20 11:13:36 +000097#undef _POSIX_THREADS
Guido van Rossum9e8181b2000-09-19 00:46:46 +000098#endif
99
Sjoerd Mullender66bca321993-12-03 16:54:45 +0000100#ifdef _POSIX_THREADS
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000101#include "thread_pthread.h"
Sjoerd Mullendere8934121993-01-13 12:08:48 +0000102#endif
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000103
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000104#ifdef C_THREADS
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000105#include "thread_cthread.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000106#endif
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000107
Guido van Rossumc3f82b61995-01-17 16:29:31 +0000108#ifdef NT_THREADS
109#include "thread_nt.h"
110#endif
111
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000112#ifdef OS2_THREADS
113#include "thread_os2.h"
114#endif
115
Guido van Rossum1a8791e1998-08-04 22:46:29 +0000116#ifdef BEOS_THREADS
117#include "thread_beos.h"
118#endif
119
Guido van Rossum2571cc81999-04-07 16:07:23 +0000120#ifdef WINCE_THREADS
121#include "thread_wince.h"
122#endif
123
Martin v. Löwis7d1cd692002-03-09 12:10:54 +0000124#ifdef PLAN9_THREADS
125#include "thread_plan9.h"
126#endif
127
Martin v. Löwisf90ae202002-06-11 06:22:31 +0000128#ifdef ATHEOS_THREADS
129#include "thread_atheos.h"
130#endif
131
Guido van Rossumf9f2e821992-08-17 08:59:08 +0000132/*
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000133#ifdef FOOBAR_THREADS
134#include "thread_foobar.h"
Guido van Rossum1984f1e1992-08-04 12:41:02 +0000135#endif
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000136*/
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000137
138#ifndef Py_HAVE_NATIVE_TLS
139/* If the platform has not supplied a platform specific
140 TLS implementation, provide our own.
141
142 This code stolen from "thread_sgi.h", where it was the only
143 implementation of an existing Python TLS API.
144*/
145/*
146 * Per-thread data ("key") support.
147 */
148
149struct key {
150 struct key *next;
151 long id;
152 int key;
153 void *value;
154};
155
156static struct key *keyhead = NULL;
157static int nkeys = 0;
158static PyThread_type_lock keymutex = NULL;
159
Tim Peters19717fa2004-10-09 17:38:29 +0000160static struct key *
161find_key(int key, void *value)
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000162{
163 struct key *p;
164 long id = PyThread_get_thread_ident();
165 for (p = keyhead; p != NULL; p = p->next) {
166 if (p->id == id && p->key == key)
167 return p;
168 }
169 if (value == NULL)
170 return NULL;
171 p = (struct key *)malloc(sizeof(struct key));
172 if (p != NULL) {
173 p->id = id;
174 p->key = key;
175 p->value = value;
176 PyThread_acquire_lock(keymutex, 1);
177 p->next = keyhead;
178 keyhead = p;
179 PyThread_release_lock(keymutex);
180 }
181 return p;
182}
183
Tim Peters19717fa2004-10-09 17:38:29 +0000184int
185PyThread_create_key(void)
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000186{
187 if (keymutex == NULL)
188 keymutex = PyThread_allocate_lock();
189 return ++nkeys;
190}
191
Tim Peters19717fa2004-10-09 17:38:29 +0000192void
193PyThread_delete_key(int key)
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000194{
195 struct key *p, **q;
196 PyThread_acquire_lock(keymutex, 1);
197 q = &keyhead;
198 while ((p = *q) != NULL) {
199 if (p->key == key) {
200 *q = p->next;
201 free((void *)p);
202 /* NB This does *not* free p->value! */
203 }
204 else
205 q = &p->next;
206 }
207 PyThread_release_lock(keymutex);
208}
209
Tim Peters19717fa2004-10-09 17:38:29 +0000210int
211PyThread_set_key_value(int key, void *value)
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000212{
213 struct key *p = find_key(key, value);
214 if (p == NULL)
215 return -1;
216 else
217 return 0;
218}
219
Tim Peters19717fa2004-10-09 17:38:29 +0000220void *
221PyThread_get_key_value(int key)
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000222{
223 struct key *p = find_key(key, NULL);
224 if (p == NULL)
225 return NULL;
226 else
227 return p->value;
228}
229
Tim Peters19717fa2004-10-09 17:38:29 +0000230void
231PyThread_delete_key_value(int key)
Mark Hammond8d98d2c2003-04-19 15:41:53 +0000232{
233 long id = PyThread_get_thread_ident();
234 struct key *p, **q;
235 PyThread_acquire_lock(keymutex, 1);
236 q = &keyhead;
237 while ((p = *q) != NULL) {
238 if (p->key == key && p->id == id) {
239 *q = p->next;
240 free((void *)p);
241 /* NB This does *not* free p->value! */
242 break;
243 }
244 else
245 q = &p->next;
246 }
247 PyThread_release_lock(keymutex);
248}
249
250#endif /* Py_HAVE_NATIVE_TLS */