annotate cos/python/Python/pystate.c @ 77:a5f3959bcab7

Added first hierarchy
author windel
date Sun, 11 Nov 2012 14:08:51 +0100
parents 7f74363f4c82
children
rev   line source
27
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2 /* Thread and interpreter state structures and their interfaces */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4 #include "Python.h"
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
5
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
6 /* --------------------------------------------------------------------------
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
7 CAUTION
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
8
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
9 Always use malloc() and free() directly in this file. A number of these
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
10 functions are advertised as safe to call when the GIL isn't held, and in
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
11 a debug build Python redirects (e.g.) PyMem_NEW (etc) to Python's debugging
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
12 obmalloc functions. Those aren't thread-safe (they rely on the GIL to avoid
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
13 the expense of doing their own locking).
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
14 -------------------------------------------------------------------------- */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
15
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
16 #ifdef HAVE_DLOPEN
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
17 #ifdef HAVE_DLFCN_H
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
18 #include <dlfcn.h>
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
19 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
20 #ifndef RTLD_LAZY
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
21 #define RTLD_LAZY 1
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
22 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
23 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
24
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
25
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
26 #ifdef WITH_THREAD
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
27 #include "pythread.h"
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
28 static PyThread_type_lock head_mutex = NULL; /* Protects interp->tstate_head */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
29 #define HEAD_INIT() (void)(head_mutex || (head_mutex = PyThread_allocate_lock()))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
30 #define HEAD_LOCK() PyThread_acquire_lock(head_mutex, WAIT_LOCK)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
31 #define HEAD_UNLOCK() PyThread_release_lock(head_mutex)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
32
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
33
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
34 /* The single PyInterpreterState used by this process'
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
35 GILState implementation
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
36 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
37 static PyInterpreterState *autoInterpreterState = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
38 static int autoTLSkey = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
39 #else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
40 #define HEAD_INIT() /* Nothing */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
41 #define HEAD_LOCK() /* Nothing */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
42 #define HEAD_UNLOCK() /* Nothing */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
43 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
44
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
45 static PyInterpreterState *interp_head = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
46
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
47 /* Assuming the current thread holds the GIL, this is the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
48 PyThreadState for the current thread. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
49 _Py_atomic_address _PyThreadState_Current = {NULL};
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
50 PyThreadFrameGetter _PyThreadState_GetFrame = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
51
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
52 #ifdef WITH_THREAD
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
53 static void _PyGILState_NoteThreadState(PyThreadState* tstate);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
54 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
55
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
56
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
57 PyInterpreterState *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
58 PyInterpreterState_New(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
59 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
60 PyInterpreterState *interp = (PyInterpreterState *)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
61 malloc(sizeof(PyInterpreterState));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
62
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
63 if (interp != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
64 HEAD_INIT();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
65 #ifdef WITH_THREAD
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
66 if (head_mutex == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
67 Py_FatalError("Can't initialize threads for interpreter");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
68 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
69 interp->modules = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
70 interp->modules_reloading = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
71 interp->modules_by_index = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
72 interp->sysdict = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
73 interp->builtins = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
74 interp->tstate_head = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
75 interp->codec_search_path = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
76 interp->codec_search_cache = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
77 interp->codec_error_registry = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
78 interp->codecs_initialized = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
79 interp->fscodec_initialized = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
80 #ifdef HAVE_DLOPEN
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
81 #ifdef RTLD_NOW
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
82 interp->dlopenflags = RTLD_NOW;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
83 #else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
84 interp->dlopenflags = RTLD_LAZY;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
85 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
86 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
87 #ifdef WITH_TSC
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
88 interp->tscdump = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
89 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
90
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
91 HEAD_LOCK();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
92 interp->next = interp_head;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
93 interp_head = interp;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
94 HEAD_UNLOCK();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
95 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
96
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
97 return interp;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
98 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
99
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
100
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
101 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
102 PyInterpreterState_Clear(PyInterpreterState *interp)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
103 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
104 PyThreadState *p;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
105 HEAD_LOCK();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
106 for (p = interp->tstate_head; p != NULL; p = p->next)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
107 PyThreadState_Clear(p);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
108 HEAD_UNLOCK();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
109 Py_CLEAR(interp->codec_search_path);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
110 Py_CLEAR(interp->codec_search_cache);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
111 Py_CLEAR(interp->codec_error_registry);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
112 Py_CLEAR(interp->modules);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
113 Py_CLEAR(interp->modules_by_index);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
114 Py_CLEAR(interp->modules_reloading);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
115 Py_CLEAR(interp->sysdict);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
116 Py_CLEAR(interp->builtins);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
117 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
118
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
119
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
120 static void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
121 zapthreads(PyInterpreterState *interp)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
122 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
123 PyThreadState *p;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
124 /* No need to lock the mutex here because this should only happen
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
125 when the threads are all really dead (XXX famous last words). */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
126 while ((p = interp->tstate_head) != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
127 PyThreadState_Delete(p);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
128 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
129 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
130
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
131
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
132 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
133 PyInterpreterState_Delete(PyInterpreterState *interp)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
134 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
135 PyInterpreterState **p;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
136 zapthreads(interp);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
137 HEAD_LOCK();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
138 for (p = &interp_head; ; p = &(*p)->next) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
139 if (*p == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
140 Py_FatalError(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
141 "PyInterpreterState_Delete: invalid interp");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
142 if (*p == interp)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
143 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
144 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
145 if (interp->tstate_head != NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
146 Py_FatalError("PyInterpreterState_Delete: remaining threads");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
147 *p = interp->next;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
148 HEAD_UNLOCK();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
149 free(interp);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
150 #ifdef WITH_THREAD
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
151 if (interp_head == NULL && head_mutex != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
152 PyThread_free_lock(head_mutex);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
153 head_mutex = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
154 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
155 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
156 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
157
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
158
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
159 /* Default implementation for _PyThreadState_GetFrame */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
160 static struct _frame *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
161 threadstate_getframe(PyThreadState *self)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
162 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
163 return self->frame;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
164 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
165
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
166 static PyThreadState *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
167 new_threadstate(PyInterpreterState *interp, int init)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
168 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
169 PyThreadState *tstate = (PyThreadState *)malloc(sizeof(PyThreadState));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
170
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
171 if (_PyThreadState_GetFrame == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
172 _PyThreadState_GetFrame = threadstate_getframe;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
173
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
174 if (tstate != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
175 tstate->interp = interp;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
176
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
177 tstate->frame = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
178 tstate->recursion_depth = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
179 tstate->overflowed = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
180 tstate->recursion_critical = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
181 tstate->tracing = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
182 tstate->use_tracing = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
183 tstate->tick_counter = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
184 tstate->gilstate_counter = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
185 tstate->async_exc = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
186 #ifdef WITH_THREAD
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
187 tstate->thread_id = PyThread_get_thread_ident();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
188 #else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
189 tstate->thread_id = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
190 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
191
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
192 tstate->dict = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
193
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
194 tstate->curexc_type = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
195 tstate->curexc_value = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
196 tstate->curexc_traceback = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
197
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
198 tstate->exc_type = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
199 tstate->exc_value = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
200 tstate->exc_traceback = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
201
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
202 tstate->c_profilefunc = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
203 tstate->c_tracefunc = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
204 tstate->c_profileobj = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
205 tstate->c_traceobj = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
206
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
207 if (init)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
208 _PyThreadState_Init(tstate);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
209
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
210 HEAD_LOCK();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
211 tstate->next = interp->tstate_head;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
212 interp->tstate_head = tstate;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
213 HEAD_UNLOCK();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
214 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
215
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
216 return tstate;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
217 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
218
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
219 PyThreadState *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
220 PyThreadState_New(PyInterpreterState *interp)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
221 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
222 return new_threadstate(interp, 1);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
223 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
224
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
225 PyThreadState *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
226 _PyThreadState_Prealloc(PyInterpreterState *interp)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
227 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
228 return new_threadstate(interp, 0);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
229 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
230
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
231 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
232 _PyThreadState_Init(PyThreadState *tstate)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
233 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
234 #ifdef WITH_THREAD
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
235 _PyGILState_NoteThreadState(tstate);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
236 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
237 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
238
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
239 PyObject*
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
240 PyState_FindModule(struct PyModuleDef* m)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
241 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
242 Py_ssize_t index = m->m_base.m_index;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
243 PyInterpreterState *state = PyThreadState_GET()->interp;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
244 PyObject *res;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
245 if (index == 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
246 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
247 if (state->modules_by_index == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
248 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
249 if (index > PyList_GET_SIZE(state->modules_by_index))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
250 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
251 res = PyList_GET_ITEM(state->modules_by_index, index);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
252 return res==Py_None ? NULL : res;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
253 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
254
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
255 int
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
256 _PyState_AddModule(PyObject* module, struct PyModuleDef* def)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
257 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
258 PyInterpreterState *state = PyThreadState_GET()->interp;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
259 if (!def)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
260 return -1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
261 if (!state->modules_by_index) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
262 state->modules_by_index = PyList_New(0);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
263 if (!state->modules_by_index)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
264 return -1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
265 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
266 while(PyList_GET_SIZE(state->modules_by_index) <= def->m_base.m_index)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
267 if (PyList_Append(state->modules_by_index, Py_None) < 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
268 return -1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
269 Py_INCREF(module);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
270 return PyList_SetItem(state->modules_by_index,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
271 def->m_base.m_index, module);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
272 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
273
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
274 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
275 PyThreadState_Clear(PyThreadState *tstate)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
276 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
277 if (Py_VerboseFlag && tstate->frame != NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
278 fprintf(stderr,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
279 "PyThreadState_Clear: warning: thread still has a frame\n");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
280
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
281 Py_CLEAR(tstate->frame);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
282
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
283 Py_CLEAR(tstate->dict);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
284 Py_CLEAR(tstate->async_exc);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
285
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
286 Py_CLEAR(tstate->curexc_type);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
287 Py_CLEAR(tstate->curexc_value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
288 Py_CLEAR(tstate->curexc_traceback);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
289
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
290 Py_CLEAR(tstate->exc_type);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
291 Py_CLEAR(tstate->exc_value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
292 Py_CLEAR(tstate->exc_traceback);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
293
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
294 tstate->c_profilefunc = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
295 tstate->c_tracefunc = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
296 Py_CLEAR(tstate->c_profileobj);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
297 Py_CLEAR(tstate->c_traceobj);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
298 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
299
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
300
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
301 /* Common code for PyThreadState_Delete() and PyThreadState_DeleteCurrent() */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
302 static void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
303 tstate_delete_common(PyThreadState *tstate)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
304 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
305 PyInterpreterState *interp;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
306 PyThreadState **p;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
307 PyThreadState *prev_p = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
308 if (tstate == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
309 Py_FatalError("PyThreadState_Delete: NULL tstate");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
310 interp = tstate->interp;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
311 if (interp == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
312 Py_FatalError("PyThreadState_Delete: NULL interp");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
313 HEAD_LOCK();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
314 for (p = &interp->tstate_head; ; p = &(*p)->next) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
315 if (*p == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
316 Py_FatalError(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
317 "PyThreadState_Delete: invalid tstate");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
318 if (*p == tstate)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
319 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
320 /* Sanity check. These states should never happen but if
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
321 * they do we must abort. Otherwise we'll end up spinning in
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
322 * in a tight loop with the lock held. A similar check is done
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
323 * in thread.c find_key(). */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
324 if (*p == prev_p)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
325 Py_FatalError(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
326 "PyThreadState_Delete: small circular list(!)"
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
327 " and tstate not found.");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
328 prev_p = *p;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
329 if ((*p)->next == interp->tstate_head)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
330 Py_FatalError(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
331 "PyThreadState_Delete: circular list(!) and"
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
332 " tstate not found.");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
333 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
334 *p = tstate->next;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
335 HEAD_UNLOCK();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
336 free(tstate);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
337 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
338
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
339
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
340 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
341 PyThreadState_Delete(PyThreadState *tstate)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
342 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
343 if (tstate == _Py_atomic_load_relaxed(&_PyThreadState_Current))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
344 Py_FatalError("PyThreadState_Delete: tstate is still current");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
345 tstate_delete_common(tstate);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
346 #ifdef WITH_THREAD
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
347 if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
348 PyThread_delete_key_value(autoTLSkey);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
349 #endif /* WITH_THREAD */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
350 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
351
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
352
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
353 #ifdef WITH_THREAD
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
354 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
355 PyThreadState_DeleteCurrent()
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
356 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
357 PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
358 &_PyThreadState_Current);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
359 if (tstate == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
360 Py_FatalError(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
361 "PyThreadState_DeleteCurrent: no current tstate");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
362 _Py_atomic_store_relaxed(&_PyThreadState_Current, NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
363 tstate_delete_common(tstate);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
364 if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
365 PyThread_delete_key_value(autoTLSkey);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
366 PyEval_ReleaseLock();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
367 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
368 #endif /* WITH_THREAD */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
369
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
370
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
371 PyThreadState *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
372 PyThreadState_Get(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
373 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
374 PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
375 &_PyThreadState_Current);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
376 if (tstate == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
377 Py_FatalError("PyThreadState_Get: no current thread");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
378
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
379 return tstate;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
380 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
381
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
382
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
383 PyThreadState *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
384 PyThreadState_Swap(PyThreadState *newts)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
385 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
386 PyThreadState *oldts = (PyThreadState*)_Py_atomic_load_relaxed(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
387 &_PyThreadState_Current);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
388
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
389 _Py_atomic_store_relaxed(&_PyThreadState_Current, newts);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
390 /* It should not be possible for more than one thread state
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
391 to be used for a thread. Check this the best we can in debug
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
392 builds.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
393 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
394 #if defined(Py_DEBUG) && defined(WITH_THREAD)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
395 if (newts) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
396 /* This can be called from PyEval_RestoreThread(). Similar
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
397 to it, we need to ensure errno doesn't change.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
398 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
399 int err = errno;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
400 PyThreadState *check = PyGILState_GetThisThreadState();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
401 if (check && check->interp == newts->interp && check != newts)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
402 Py_FatalError("Invalid thread state for this thread");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
403 errno = err;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
404 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
405 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
406 return oldts;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
407 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
408
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
409 /* An extension mechanism to store arbitrary additional per-thread state.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
410 PyThreadState_GetDict() returns a dictionary that can be used to hold such
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
411 state; the caller should pick a unique key and store its state there. If
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
412 PyThreadState_GetDict() returns NULL, an exception has *not* been raised
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
413 and the caller should assume no per-thread state is available. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
414
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
415 PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
416 PyThreadState_GetDict(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
417 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
418 PyThreadState *tstate = (PyThreadState*)_Py_atomic_load_relaxed(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
419 &_PyThreadState_Current);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
420 if (tstate == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
421 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
422
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
423 if (tstate->dict == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
424 PyObject *d;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
425 tstate->dict = d = PyDict_New();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
426 if (d == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
427 PyErr_Clear();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
428 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
429 return tstate->dict;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
430 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
431
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
432
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
433 /* Asynchronously raise an exception in a thread.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
434 Requested by Just van Rossum and Alex Martelli.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
435 To prevent naive misuse, you must write your own extension
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
436 to call this, or use ctypes. Must be called with the GIL held.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
437 Returns the number of tstates modified (normally 1, but 0 if `id` didn't
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
438 match any known thread id). Can be called with exc=NULL to clear an
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
439 existing async exception. This raises no exceptions. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
440
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
441 int
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
442 PyThreadState_SetAsyncExc(long id, PyObject *exc) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
443 PyThreadState *tstate = PyThreadState_GET();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
444 PyInterpreterState *interp = tstate->interp;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
445 PyThreadState *p;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
446
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
447 /* Although the GIL is held, a few C API functions can be called
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
448 * without the GIL held, and in particular some that create and
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
449 * destroy thread and interpreter states. Those can mutate the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
450 * list of thread states we're traversing, so to prevent that we lock
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
451 * head_mutex for the duration.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
452 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
453 HEAD_LOCK();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
454 for (p = interp->tstate_head; p != NULL; p = p->next) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
455 if (p->thread_id == id) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
456 /* Tricky: we need to decref the current value
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
457 * (if any) in p->async_exc, but that can in turn
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
458 * allow arbitrary Python code to run, including
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
459 * perhaps calls to this function. To prevent
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
460 * deadlock, we need to release head_mutex before
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
461 * the decref.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
462 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
463 PyObject *old_exc = p->async_exc;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
464 Py_XINCREF(exc);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
465 p->async_exc = exc;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
466 HEAD_UNLOCK();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
467 Py_XDECREF(old_exc);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
468 _PyEval_SignalAsyncExc();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
469 return 1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
470 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
471 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
472 HEAD_UNLOCK();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
473 return 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
474 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
475
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
476
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
477 /* Routines for advanced debuggers, requested by David Beazley.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
478 Don't use unless you know what you are doing! */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
479
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
480 PyInterpreterState *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
481 PyInterpreterState_Head(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
482 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
483 return interp_head;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
484 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
485
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
486 PyInterpreterState *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
487 PyInterpreterState_Next(PyInterpreterState *interp) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
488 return interp->next;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
489 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
490
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
491 PyThreadState *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
492 PyInterpreterState_ThreadHead(PyInterpreterState *interp) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
493 return interp->tstate_head;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
494 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
495
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
496 PyThreadState *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
497 PyThreadState_Next(PyThreadState *tstate) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
498 return tstate->next;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
499 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
500
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
501 /* The implementation of sys._current_frames(). This is intended to be
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
502 called with the GIL held, as it will be when called via
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
503 sys._current_frames(). It's possible it would work fine even without
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
504 the GIL held, but haven't thought enough about that.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
505 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
506 PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
507 _PyThread_CurrentFrames(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
508 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
509 PyObject *result;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
510 PyInterpreterState *i;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
511
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
512 result = PyDict_New();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
513 if (result == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
514 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
515
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
516 /* for i in all interpreters:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
517 * for t in all of i's thread states:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
518 * if t's frame isn't NULL, map t's id to its frame
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
519 * Because these lists can mutate even when the GIL is held, we
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
520 * need to grab head_mutex for the duration.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
521 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
522 HEAD_LOCK();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
523 for (i = interp_head; i != NULL; i = i->next) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
524 PyThreadState *t;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
525 for (t = i->tstate_head; t != NULL; t = t->next) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
526 PyObject *id;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
527 int stat;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
528 struct _frame *frame = t->frame;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
529 if (frame == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
530 continue;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
531 id = PyLong_FromLong(t->thread_id);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
532 if (id == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
533 goto Fail;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
534 stat = PyDict_SetItem(result, id, (PyObject *)frame);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
535 Py_DECREF(id);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
536 if (stat < 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
537 goto Fail;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
538 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
539 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
540 HEAD_UNLOCK();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
541 return result;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
542
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
543 Fail:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
544 HEAD_UNLOCK();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
545 Py_DECREF(result);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
546 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
547 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
548
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
549 /* Python "auto thread state" API. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
550 #ifdef WITH_THREAD
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
551
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
552 /* Keep this as a static, as it is not reliable! It can only
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
553 ever be compared to the state for the *current* thread.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
554 * If not equal, then it doesn't matter that the actual
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
555 value may change immediately after comparison, as it can't
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
556 possibly change to the current thread's state.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
557 * If equal, then the current thread holds the lock, so the value can't
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
558 change until we yield the lock.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
559 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
560 static int
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
561 PyThreadState_IsCurrent(PyThreadState *tstate)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
562 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
563 /* Must be the tstate for this thread */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
564 assert(PyGILState_GetThisThreadState()==tstate);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
565 return tstate == _Py_atomic_load_relaxed(&_PyThreadState_Current);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
566 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
567
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
568 /* Internal initialization/finalization functions called by
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
569 Py_Initialize/Py_Finalize
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
570 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
571 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
572 _PyGILState_Init(PyInterpreterState *i, PyThreadState *t)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
573 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
574 assert(i && t); /* must init with valid states */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
575 autoTLSkey = PyThread_create_key();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
576 if (autoTLSkey == -1)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
577 Py_FatalError("Could not allocate TLS entry");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
578 autoInterpreterState = i;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
579 assert(PyThread_get_key_value(autoTLSkey) == NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
580 assert(t->gilstate_counter == 0);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
581
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
582 _PyGILState_NoteThreadState(t);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
583 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
584
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
585 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
586 _PyGILState_Fini(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
587 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
588 PyThread_delete_key(autoTLSkey);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
589 autoInterpreterState = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
590 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
591
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
592 /* Reset the TLS key - called by PyOS_AfterFork().
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
593 * This should not be necessary, but some - buggy - pthread implementations
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
594 * don't reset TLS upon fork(), see issue #10517.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
595 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
596 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
597 _PyGILState_Reinit(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
598 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
599 PyThreadState *tstate = PyGILState_GetThisThreadState();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
600 PyThread_delete_key(autoTLSkey);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
601 if ((autoTLSkey = PyThread_create_key()) == -1)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
602 Py_FatalError("Could not allocate TLS entry");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
603
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
604 /* If the thread had an associated auto thread state, reassociate it with
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
605 * the new key. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
606 if (tstate && PyThread_set_key_value(autoTLSkey, (void *)tstate) < 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
607 Py_FatalError("Couldn't create autoTLSkey mapping");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
608 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
609
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
610 /* When a thread state is created for a thread by some mechanism other than
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
611 PyGILState_Ensure, it's important that the GILState machinery knows about
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
612 it so it doesn't try to create another thread state for the thread (this is
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
613 a better fix for SF bug #1010677 than the first one attempted).
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
614 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
615 static void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
616 _PyGILState_NoteThreadState(PyThreadState* tstate)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
617 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
618 /* If autoTLSkey isn't initialized, this must be the very first
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
619 threadstate created in Py_Initialize(). Don't do anything for now
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
620 (we'll be back here when _PyGILState_Init is called). */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
621 if (!autoInterpreterState)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
622 return;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
623
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
624 /* Stick the thread state for this thread in thread local storage.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
625
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
626 The only situation where you can legitimately have more than one
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
627 thread state for an OS level thread is when there are multiple
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
628 interpreters, when:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
629
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
630 a) You shouldn't really be using the PyGILState_ APIs anyway,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
631 and:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
632
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
633 b) The slightly odd way PyThread_set_key_value works (see
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
634 comments by its implementation) means that the first thread
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
635 state created for that given OS level thread will "win",
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
636 which seems reasonable behaviour.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
637 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
638 if (PyThread_set_key_value(autoTLSkey, (void *)tstate) < 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
639 Py_FatalError("Couldn't create autoTLSkey mapping");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
640
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
641 /* PyGILState_Release must not try to delete this thread state. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
642 tstate->gilstate_counter = 1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
643 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
644
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
645 /* The public functions */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
646 PyThreadState *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
647 PyGILState_GetThisThreadState(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
648 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
649 if (autoInterpreterState == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
650 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
651 return (PyThreadState *)PyThread_get_key_value(autoTLSkey);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
652 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
653
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
654 PyGILState_STATE
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
655 PyGILState_Ensure(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
656 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
657 int current;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
658 PyThreadState *tcur;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
659 /* Note that we do not auto-init Python here - apart from
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
660 potential races with 2 threads auto-initializing, pep-311
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
661 spells out other issues. Embedders are expected to have
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
662 called Py_Initialize() and usually PyEval_InitThreads().
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
663 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
664 assert(autoInterpreterState); /* Py_Initialize() hasn't been called! */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
665 tcur = (PyThreadState *)PyThread_get_key_value(autoTLSkey);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
666 if (tcur == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
667 /* Create a new thread state for this thread */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
668 tcur = PyThreadState_New(autoInterpreterState);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
669 if (tcur == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
670 Py_FatalError("Couldn't create thread-state for new thread");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
671 /* This is our thread state! We'll need to delete it in the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
672 matching call to PyGILState_Release(). */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
673 tcur->gilstate_counter = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
674 current = 0; /* new thread state is never current */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
675 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
676 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
677 current = PyThreadState_IsCurrent(tcur);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
678 if (current == 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
679 PyEval_RestoreThread(tcur);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
680 /* Update our counter in the thread-state - no need for locks:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
681 - tcur will remain valid as we hold the GIL.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
682 - the counter is safe as we are the only thread "allowed"
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
683 to modify this value
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
684 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
685 ++tcur->gilstate_counter;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
686 return current ? PyGILState_LOCKED : PyGILState_UNLOCKED;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
687 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
688
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
689 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
690 PyGILState_Release(PyGILState_STATE oldstate)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
691 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
692 PyThreadState *tcur = (PyThreadState *)PyThread_get_key_value(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
693 autoTLSkey);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
694 if (tcur == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
695 Py_FatalError("auto-releasing thread-state, "
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
696 "but no thread-state for this thread");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
697 /* We must hold the GIL and have our thread state current */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
698 /* XXX - remove the check - the assert should be fine,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
699 but while this is very new (April 2003), the extra check
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
700 by release-only users can't hurt.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
701 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
702 if (! PyThreadState_IsCurrent(tcur))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
703 Py_FatalError("This thread state must be current when releasing");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
704 assert(PyThreadState_IsCurrent(tcur));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
705 --tcur->gilstate_counter;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
706 assert(tcur->gilstate_counter >= 0); /* illegal counter value */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
707
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
708 /* If we're going to destroy this thread-state, we must
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
709 * clear it while the GIL is held, as destructors may run.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
710 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
711 if (tcur->gilstate_counter == 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
712 /* can't have been locked when we created it */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
713 assert(oldstate == PyGILState_UNLOCKED);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
714 PyThreadState_Clear(tcur);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
715 /* Delete the thread-state. Note this releases the GIL too!
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
716 * It's vital that the GIL be held here, to avoid shutdown
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
717 * races; see bugs 225673 and 1061968 (that nasty bug has a
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
718 * habit of coming back).
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
719 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
720 PyThreadState_DeleteCurrent();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
721 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
722 /* Release the lock if necessary */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
723 else if (oldstate == PyGILState_UNLOCKED)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
724 PyEval_SaveThread();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
725 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
726
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
727 #endif /* WITH_THREAD */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
728
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
729