Last active
March 24, 2020 04:43
-
-
Save reed-lau/a78657a8c9da6efcbc6d7cbc98ec1fa1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define GET_TSTATE() \ | |
((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current)) | |
#define SET_TSTATE(value) \ | |
_Py_atomic_store_relaxed(&_PyThreadState_Current, (Py_uintptr_t)(value)) | |
PyThreadState * | |
PyThreadState_Swap(PyThreadState *newts) | |
{ | |
PyThreadState *oldts = GET_TSTATE(); | |
SET_TSTATE(newts); | |
/* It should not be possible for more than one thread state | |
to be used for a thread. Check this the best we can in debug | |
builds. | |
*/ | |
#if defined(Py_DEBUG) && defined(WITH_THREAD) | |
if (newts) { | |
/* This can be called from PyEval_RestoreThread(). Similar | |
to it, we need to ensure errno doesn't change. | |
*/ | |
int err = errno; | |
PyThreadState *check = PyGILState_GetThisThreadState(); | |
if (check && check->interp == newts->interp && check != newts) | |
Py_FatalError("Invalid thread state for this thread"); | |
errno = err; | |
} | |
#endif | |
return oldts; | |
} | |
PyThreadState * | |
PyEval_SaveThread(void) | |
{ | |
PyThreadState *tstate = PyThreadState_Swap(NULL); | |
if (tstate == NULL) | |
Py_FatalError("PyEval_SaveThread: NULL tstate"); | |
if (gil_created()) | |
drop_gil(tstate); | |
return tstate; | |
} | |
void | |
PyEval_RestoreThread(PyThreadState *tstate) | |
{ | |
if (tstate == NULL) | |
Py_FatalError("PyEval_RestoreThread: NULL tstate"); | |
if (gil_created()) { | |
int err = errno; | |
take_gil(tstate); | |
/* _Py_Finalizing is protected by the GIL */ | |
if (_Py_Finalizing && tstate != _Py_Finalizing) { | |
drop_gil(tstate); | |
PyThread_exit_thread(); | |
assert(0); /* unreachable */ | |
} | |
errno = err; | |
} | |
PyThreadState_Swap(tstate); | |
} | |
void | |
PyThread_exit_thread(void) | |
{ | |
dprintf(("PyThread_exit_thread called\n")); | |
if (!initialized) | |
exit(0); | |
pthread_exit(0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment