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