26 PythonThread(PyObject *
function, PyObject *args,
27 const std::string &name,
const std::string &sync_name) :
35 if (!PyCallable_Check(_function)) {
36 nassert_raise(
"Invalid function passed to PythonThread constructor");
41 #ifndef SIMPLE_THREADS 43 #ifdef WITH_THREAD // This symbol defined within Python.h 56 #if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS) 57 PyGILState_STATE gstate;
58 gstate = PyGILState_Ensure();
65 #if defined(HAVE_THREADS) && !defined(SIMPLE_THREADS) 66 PyGILState_Release(gstate);
77 PyObject *PythonThread::
81 if (_result ==
nullptr) {
94 PyObject *PythonThread::
103 set_args(PyObject *args) {
106 if (args == Py_None) {
108 _args = PyTuple_New(0);
111 if (PySequence_Check(args)) {
112 _args = PySequence_Tuple(args);
114 if (_args ==
nullptr) {
115 Dtool_Raise_TypeError(
"PythonThread args must be a tuple");
127 PyObject *PythonThread::
128 call_python_func(PyObject *
function, PyObject *args) {
129 Thread *current_thread = get_current_thread();
133 PyObject *result =
nullptr;
135 if (current_thread == get_main_thread()) {
137 result = PyObject_Call(
function, args,
nullptr);
139 if (result ==
nullptr) {
140 if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_SystemExit)) {
147 PyObject *exc, *val, *tb;
148 PyErr_Fetch(&exc, &val, &tb);
153 PyErr_Restore(exc, val, tb);
156 PyErr_Restore(exc, val, tb);
164 nassert_raise(
"threading support disabled");
168 #ifdef SIMPLE_THREADS 185 PyThreadState *orig_thread_state = PyThreadState_Get();
186 PyInterpreterState *istate = orig_thread_state->interp;
187 PyThreadState *new_thread_state;
188 if (thread_states.empty()) {
189 new_thread_state = PyThreadState_New(istate);
191 new_thread_state = thread_states.back();
192 thread_states.pop_back();
194 PyThreadState_Swap(new_thread_state);
197 result = PyObject_Call(
function, args,
nullptr);
198 if (result ==
nullptr && PyErr_Occurred()) {
201 PyObject *exc, *val, *tb;
202 PyErr_Fetch(&exc, &val, &tb);
205 <<
"Exception occurred within " << *current_thread <<
"\n";
212 PyErr_Restore(exc, val, tb);
215 PyThreadState_Swap(orig_thread_state);
216 thread_states.push_back(new_thread_state);
220 PyErr_Restore(exc, val, tb);
229 PyThreadState_Swap(orig_thread_state);
230 thread_states.push_back(new_thread_state);
235 #else // SIMPLE_THREADS 237 PyGILState_STATE gstate;
238 gstate = PyGILState_Ensure();
241 result = PyObject_Call(
function, args,
nullptr);
242 if (result ==
nullptr && PyErr_Occurred()) {
245 PyObject *exc, *val, *tb;
246 PyErr_Fetch(&exc, &val, &tb);
249 <<
"Exception occurred within " << *current_thread <<
"\n";
256 PyErr_Restore(exc, val, tb);
259 PyGILState_Release(gstate);
261 PyErr_Restore(exc, val, tb);
264 PyGILState_Release(gstate);
268 #endif // SIMPLE_THREADS 269 #endif // HAVE_THREADS 274 #endif // HAVE_PYTHON 281 _result = call_python_func(_function, _args);
284 #endif // HAVE_PYTHON PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is our own Panda specialization on the default STL vector.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_main_thread
Returns a pointer to the "main" Thread object–this is the Thread that started the whole process.
void join()
Blocks the calling process until the thread terminates.
A thread; that is, a lightweight process.
TypeHandle is the identifier used to differentiate C++ class types.