Panda3D

pythonThread.cxx

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
 All Classes Functions Variables Enumerations