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