00001 // Filename: pythonThread.cxx 00002 // Created by: drose (13Apr07) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "pythonThread.h" 00016 #include "pnotify.h" 00017 00018 #ifdef HAVE_PYTHON 00019 00020 TypeHandle PythonThread::_type_handle; 00021 00022 //////////////////////////////////////////////////////////////////// 00023 // Function: PythonThread::Constructor 00024 // Access: Published 00025 // Description: 00026 //////////////////////////////////////////////////////////////////// 00027 PythonThread:: 00028 PythonThread(PyObject *function, PyObject *args, 00029 const string &name, const string &sync_name) : 00030 Thread(name, sync_name) 00031 { 00032 _function = function; 00033 Py_INCREF(_function); 00034 _args = NULL; 00035 _result = NULL; 00036 00037 if (!PyCallable_Check(_function)) { 00038 nassert_raise("Invalid function passed to PythonThread constructor"); 00039 } 00040 00041 if (args == Py_None) { 00042 // None means no arguments; create an empty tuple. 00043 _args = PyTuple_New(0); 00044 } else { 00045 _args = NULL; 00046 if (PySequence_Check(args)) { 00047 _args = PySequence_Tuple(args); 00048 } 00049 if (_args == NULL) { 00050 nassert_raise("Invalid args passed to PythonThread constructor"); 00051 } 00052 } 00053 } 00054 00055 //////////////////////////////////////////////////////////////////// 00056 // Function: PythonThread::Destructor 00057 // Access: Published, Virtual 00058 // Description: 00059 //////////////////////////////////////////////////////////////////// 00060 PythonThread:: 00061 ~PythonThread() { 00062 Py_DECREF(_function); 00063 Py_XDECREF(_args); 00064 Py_XDECREF(_result); 00065 } 00066 00067 //////////////////////////////////////////////////////////////////// 00068 // Function: PythonThread::join 00069 // Access: Published 00070 // Description: Blocks the calling process until the thread 00071 // terminates. If the thread has already terminated, 00072 // this returns immediately. 00073 // 00074 // The PythonThread flavor of this function returns the 00075 // same value returned by the thread function. 00076 //////////////////////////////////////////////////////////////////// 00077 PyObject *PythonThread:: 00078 join() { 00079 Thread::join(); 00080 00081 if (_result == NULL) { 00082 // No result; return None. 00083 return Py_BuildValue(""); 00084 } 00085 00086 Py_INCREF(_result); 00087 return _result; 00088 } 00089 00090 //////////////////////////////////////////////////////////////////// 00091 // Function: PythonThread::thread_main 00092 // Access: Protected, Virtual 00093 // Description: 00094 //////////////////////////////////////////////////////////////////// 00095 void PythonThread:: 00096 thread_main() { 00097 _result = call_python_func(_function, _args); 00098 } 00099 00100 #endif // HAVE_PYTHON