Panda3D
 All Classes Functions Variables Enumerations
thread.cxx
00001 // Filename: thread.cxx
00002 // Created by:  drose (08Aug02)
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 "thread.h"
00016 #include "mainThread.h"
00017 #include "externalThread.h"
00018 #include "config_pipeline.h"
00019 #include "mutexDebug.h"
00020 #include "conditionVarDebug.h"
00021 #include "conditionVarFullDebug.h"
00022 
00023 Thread *Thread::_main_thread;
00024 Thread *Thread::_external_thread;
00025 TypeHandle Thread::_type_handle;
00026 
00027 ////////////////////////////////////////////////////////////////////
00028 //     Function: Thread::Constructor
00029 //       Access: Protected
00030 //  Description: Creates a new Thread object, but does not
00031 //               immediately start executing it.  This gives the
00032 //               caller a chance to store it in a PT(Thread) object,
00033 //               if desired, before the thread gets a chance to
00034 //               terminate and destruct itself.
00035 //
00036 //               Call start() to begin thread execution.
00037 //
00038 //               The name should be unique for each thread (though
00039 //               this is not enforced, and not strictly required).
00040 //               The sync_name can be shared between multiple
00041 //               different threads; threads that run synchronously
00042 //               with each other should be given the same sync_name,
00043 //               for the benefit of PStats.
00044 ////////////////////////////////////////////////////////////////////
00045 Thread::
00046 Thread(const string &name, const string &sync_name) : 
00047   Namable(name), 
00048   _sync_name(sync_name), 
00049   _impl(this) 
00050 {
00051   _started = false;
00052   _pstats_index = -1;
00053   _pstats_callback = NULL;
00054   _pipeline_stage = 0;
00055   _joinable = false;
00056   _current_task = NULL;
00057 
00058 #ifdef HAVE_PYTHON
00059   _python_data = Py_None;
00060   Py_INCREF(_python_data);
00061 #endif
00062 
00063 #ifdef DEBUG_THREADS
00064   _blocked_on_mutex = NULL;
00065   _waiting_on_cvar = NULL;
00066   _waiting_on_cvar_full = NULL;
00067 #endif
00068 
00069 #if defined(HAVE_PYTHON) && !defined(SIMPLE_THREADS)
00070   // Ensure that the Python threading system is initialized and ready
00071   // to go.
00072 #ifdef WITH_THREAD  // This symbol defined within Python.h
00073   PyEval_InitThreads();
00074 #endif
00075 #endif
00076 }
00077 
00078 ////////////////////////////////////////////////////////////////////
00079 //     Function: Thread::Destructor
00080 //       Access: Published, Virtual
00081 //  Description:
00082 ////////////////////////////////////////////////////////////////////
00083 Thread::
00084 ~Thread() {
00085 #ifdef HAVE_PYTHON
00086   Py_DECREF(_python_data);
00087 #endif
00088 
00089 #ifdef DEBUG_THREADS
00090   nassertv(_blocked_on_mutex == NULL &&
00091            _waiting_on_cvar == NULL &&
00092            _waiting_on_cvar_full == NULL);
00093 #endif
00094 }
00095 
00096 ////////////////////////////////////////////////////////////////////
00097 //     Function: Thread::bind_thread
00098 //       Access: Published, Static
00099 //  Description: Returns a new Panda Thread object associated with the
00100 //               current thread (which has been created externally).
00101 //               This can be used to bind a unique Panda Thread object
00102 //               with an external thread, such as a new Python thread.
00103 //
00104 //               It is particularly useful to bind a Panda Thread
00105 //               object to an external thread for the purposes of
00106 //               PStats monitoring.  Without this call, each external
00107 //               thread will be assigned the same global
00108 //               ExternalThread object, which means they will all
00109 //               appear in the same PStats graph.
00110 //
00111 //               It is the caller's responsibility to save the
00112 //               returned Thread pointer for the lifetime of the
00113 //               external thread.  It is an error for the Thread
00114 //               pointer to destruct while the external thread is
00115 //               still in the system.
00116 //
00117 //               It is also an error to call this method from the main
00118 //               thread, or twice within a given thread, unless it is
00119 //               given the same name each time (in which case the same
00120 //               pointer will be returned each time).
00121 ////////////////////////////////////////////////////////////////////
00122 PT(Thread) Thread::
00123 bind_thread(const string &name, const string &sync_name) {
00124   Thread *current_thread = get_current_thread();
00125   if (current_thread != get_external_thread()) {
00126     // This thread already has an associated thread.
00127     nassertr(current_thread->get_name() == name && 
00128              current_thread->get_sync_name() == sync_name, current_thread);
00129     return current_thread;
00130   }
00131 
00132   PT(Thread) thread = new ExternalThread(name, sync_name);
00133   ThreadImpl::bind_thread(thread);
00134   return thread;
00135 }
00136 
00137 ////////////////////////////////////////////////////////////////////
00138 //     Function: Thread::set_pipeline_stage
00139 //       Access: Published
00140 //  Description: Specifies the Pipeline stage number associated with
00141 //               this thread.  The default stage is 0 if no stage is
00142 //               specified otherwise.
00143 //
00144 //               This must be a value in the range [0
00145 //               .. pipeline->get_num_stages() - 1].  It specifies the
00146 //               values that this thread observes for all pipelined
00147 //               data.  Typically, an application thread will leave
00148 //               this at 0, but a render thread may set it to 1 or 2
00149 //               (to operate on the previous frame's data, or the
00150 //               second previous frame's data).
00151 ////////////////////////////////////////////////////////////////////
00152 void Thread::
00153 set_pipeline_stage(int pipeline_stage) {
00154 #ifdef THREADED_PIPELINE
00155   _pipeline_stage = pipeline_stage;
00156 #else
00157   if (pipeline_stage != 0) {
00158     pipeline_cat.warning()
00159       << "Requested pipeline stage " << pipeline_stage
00160       << " but multithreaded render pipelines not enabled in build.\n";
00161   }
00162   _pipeline_stage = 0;
00163 #endif
00164 }
00165 
00166 ////////////////////////////////////////////////////////////////////
00167 //     Function: Thread::output
00168 //       Access: Published, Virtual
00169 //  Description:
00170 ////////////////////////////////////////////////////////////////////
00171 void Thread::
00172 output(ostream &out) const {
00173   out << get_type() << " " << get_name();
00174 }
00175 
00176 ////////////////////////////////////////////////////////////////////
00177 //     Function: Thread::output_blocker
00178 //       Access: Published
00179 //  Description: Writes a description of the mutex or condition
00180 //               variable that this thread is blocked on.  Writes
00181 //               nothing if there is no blocker, or if we are not in
00182 //               DEBUG_THREADS mode.
00183 ////////////////////////////////////////////////////////////////////
00184 void Thread::
00185 output_blocker(ostream &out) const {
00186 #ifdef DEBUG_THREADS
00187   if (_blocked_on_mutex != (MutexDebug *)NULL) {
00188     _blocked_on_mutex->output_with_holder(out);
00189   } else if (_waiting_on_cvar != (ConditionVarDebug *)NULL) {
00190     out << *_waiting_on_cvar;
00191   } else if (_waiting_on_cvar_full != (ConditionVarFullDebug *)NULL) {
00192     out << *_waiting_on_cvar_full;
00193   }
00194 #endif  // DEBUG_THREADS
00195 }
00196 
00197 ////////////////////////////////////////////////////////////////////
00198 //     Function: Thread::write_status
00199 //       Access: Published, Static
00200 //  Description:
00201 ////////////////////////////////////////////////////////////////////
00202 void Thread::
00203 write_status(ostream &out) {
00204 #if defined(HAVE_THREADS) && defined(SIMPLE_THREADS)
00205   ThreadImpl::write_status(out);
00206 #endif
00207 }
00208 
00209 ////////////////////////////////////////////////////////////////////
00210 //     Function: Thread::start
00211 //       Access: Public
00212 //  Description: Starts the thread executing.  It is only valid to
00213 //               call this once.
00214 //
00215 //               The thread will begin executing its thread_main()
00216 //               function, and will terminate when thread_main()
00217 //               returns.
00218 //
00219 //               priority is intended as a hint to the relative
00220 //               importance of this thread.  This may be ignored by
00221 //               the thread implementation.
00222 //
00223 //               joinable should be set true if you intend to call
00224 //               join() to wait for the thread to terminate, or false
00225 //               if you don't care and you will never call join().
00226 //               Note that the reference count on the Thread object is
00227 //               incremented while the thread itself is running, so if
00228 //               you just want to fire and forget a thread, you may
00229 //               pass joinable = false, and never store the Thread
00230 //               object.  It will automatically destruct itself when
00231 //               it finishes.
00232 //
00233 //               The return value is true if the thread is
00234 //               successfully started, false otherwise.
00235 ////////////////////////////////////////////////////////////////////
00236 bool Thread::
00237 start(ThreadPriority priority, bool joinable) {
00238   nassertr(!_started, false);
00239 
00240   if (!support_threads) {
00241     thread_cat->warning()
00242       << *this << " could not be started: support-threads is false.\n";
00243     return false;
00244   }
00245 
00246   _joinable = joinable;
00247   _started = _impl.start(priority, joinable);
00248 
00249   if (!_started) {
00250     thread_cat->warning()
00251       << *this << " could not be started!\n";
00252   }
00253 
00254   return _started;
00255 }
00256 
00257 #ifdef HAVE_PYTHON
00258 ////////////////////////////////////////////////////////////////////
00259 //     Function: Thread::set_python_data
00260 //       Access: Published
00261 //  Description: Sets an arbitrary Python object that may be
00262 //               associated with this thread object.  This is just for
00263 //               the purposes of associated arbitrary Python data with
00264 //               the C++ object; other than managing the reference
00265 //               count, the C++ code does nothing with this object.
00266 ////////////////////////////////////////////////////////////////////
00267 void Thread::
00268 set_python_data(PyObject *python_data) {
00269   Py_DECREF(_python_data);
00270   _python_data = python_data;
00271   Py_INCREF(_python_data);
00272 }
00273 #endif  // HAVE_PYTHON
00274 
00275 #ifdef HAVE_PYTHON
00276 ////////////////////////////////////////////////////////////////////
00277 //     Function: Thread::get_python_data
00278 //       Access: Published
00279 //  Description: Returns the Python object that was set with
00280 //               set_python_data().
00281 ////////////////////////////////////////////////////////////////////
00282 PyObject *Thread::
00283 get_python_data() const {
00284   Py_INCREF(_python_data);
00285   return _python_data;
00286 }
00287 #endif  // HAVE_PYTHON
00288 
00289 #ifdef HAVE_PYTHON
00290 ////////////////////////////////////////////////////////////////////
00291 //     Function: Thread::call_python_func
00292 //       Access: Public
00293 //  Description: Internal function to safely call a Python function
00294 //               within a sub-thread, that might execute in parallel
00295 //               with existing Python code.  The return value is the
00296 //               return value of the Python function, or NULL if there
00297 //               was an exception.
00298 ////////////////////////////////////////////////////////////////////
00299 PyObject *Thread::
00300 call_python_func(PyObject *function, PyObject *args) {
00301   nassertr(this == get_current_thread(), NULL);
00302 
00303   // Create a new Python thread state data structure, so Python can
00304   // properly lock itself.  
00305   PyObject *result = NULL;
00306 
00307   if (this == get_main_thread()) {
00308     // In the main thread, just call the function.
00309     result = PyObject_Call(function, args, NULL);
00310 
00311     if (result == (PyObject *)NULL) {
00312       // Temporarily save and restore the exception state so we can print a
00313       // callback on-the-spot.
00314       PyObject *exc, *val, *tb;
00315       PyErr_Fetch(&exc, &val, &tb);
00316       
00317       Py_XINCREF(exc);
00318       Py_XINCREF(val);
00319       Py_XINCREF(tb);
00320       PyErr_Restore(exc, val, tb);
00321       PyErr_Print();
00322       
00323       PyErr_Restore(exc, val, tb);
00324     }
00325 
00326   } else {
00327 #ifndef HAVE_THREADS
00328     // Shouldn't be possible to come here without having some kind of
00329     // threading support enabled.
00330     nassertr(false, NULL);
00331 #else
00332 
00333 #ifdef SIMPLE_THREADS
00334     // We can't use the PyGILState interface, which assumes we are
00335     // using true OS-level threading.  PyGILState enforces policies
00336     // like only one thread state per OS-level thread, which is not
00337     // true in the case of SIMPLE_THREADS.
00338 
00339     // For some reason I don't fully understand, I'm getting a crash
00340     // when I clean up old PyThreadState objects with
00341     // PyThreadState_Delete().  It appears that the thread state is
00342     // still referenced somewhere at the time I call delete, and the
00343     // crash occurs because I've deleted an active pointer.
00344 
00345     // Storing these pointers in a vector for permanent recycling
00346     // seems to avoid this problem.  I wish I understood better what's
00347     // going wrong, but I guess this workaround will do.
00348     static pvector<PyThreadState *> thread_states;
00349 
00350     PyThreadState *orig_thread_state = PyThreadState_Get();
00351     PyInterpreterState *istate = orig_thread_state->interp;
00352     PyThreadState *new_thread_state;
00353     if (thread_states.empty()) {
00354       new_thread_state = PyThreadState_New(istate);
00355     } else {
00356       new_thread_state = thread_states.back();
00357       thread_states.pop_back();
00358     }
00359     PyThreadState_Swap(new_thread_state);
00360     
00361     // Call the user's function.
00362     result = PyObject_Call(function, args, NULL);
00363     if (result == (PyObject *)NULL && PyErr_Occurred()) {
00364       // We got an exception.  Move the exception from the current
00365       // thread into the main thread, so it can be handled there.
00366       PyObject *exc, *val, *tb;
00367       PyErr_Fetch(&exc, &val, &tb);
00368 
00369       thread_cat.error()
00370         << "Exception occurred within " << *this << "\n";
00371 
00372       // Temporarily restore the exception state so we can print a
00373       // callback on-the-spot.
00374       Py_XINCREF(exc);
00375       Py_XINCREF(val);
00376       Py_XINCREF(tb);
00377       PyErr_Restore(exc, val, tb);
00378       PyErr_Print();
00379 
00380       PyThreadState_Swap(orig_thread_state);
00381       thread_states.push_back(new_thread_state);
00382       //PyThreadState_Clear(new_thread_state);
00383       //PyThreadState_Delete(new_thread_state);
00384 
00385       PyErr_Restore(exc, val, tb);
00386 
00387       // Now attempt to force the main thread to the head of the ready
00388       // queue, so it can respond to the exception immediately.  This
00389       // only works if the main thread is not blocked, of course.
00390       Thread::get_main_thread()->preempt();
00391 
00392     } else {
00393       // No exception.  Restore the thread state normally.
00394       PyThreadState *state = PyThreadState_Swap(orig_thread_state);
00395       thread_states.push_back(new_thread_state);
00396       //PyThreadState_Clear(new_thread_state);
00397       //PyThreadState_Delete(new_thread_state);
00398     }
00399     
00400 #else  // SIMPLE_THREADS
00401     // With true threading enabled, we're better off using PyGILState.
00402     PyGILState_STATE gstate;
00403     gstate = PyGILState_Ensure();
00404     
00405     // Call the user's function.
00406     result = PyObject_Call(function, args, NULL);
00407     if (result == (PyObject *)NULL && PyErr_Occurred()) {
00408       // We got an exception.  Move the exception from the current
00409       // thread into the main thread, so it can be handled there.
00410       PyObject *exc, *val, *tb;
00411       PyErr_Fetch(&exc, &val, &tb);
00412 
00413       thread_cat.error()
00414         << "Exception occurred within " << *this << "\n";
00415 
00416       // Temporarily restore the exception state so we can print a
00417       // callback on-the-spot.
00418       Py_XINCREF(exc);
00419       Py_XINCREF(val);
00420       Py_XINCREF(tb);
00421       PyErr_Restore(exc, val, tb);
00422       PyErr_Print();
00423 
00424       PyGILState_Release(gstate);
00425 
00426       PyErr_Restore(exc, val, tb);
00427     } else {
00428       // No exception.  Restore the thread state normally.
00429       PyGILState_Release(gstate);
00430     }
00431     
00432 
00433 #endif  // SIMPLE_THREADS
00434 #endif  // HAVE_THREADS
00435   }
00436 
00437   return result;
00438 }
00439 #endif  // HAVE_PYTHON
00440 
00441 #ifdef HAVE_PYTHON
00442 ////////////////////////////////////////////////////////////////////
00443 //     Function: Thread::handle_python_exception
00444 //       Access: Public
00445 //  Description: Called when a Python exception is raised during
00446 //               processing of a thread.  Gets the error string and
00447 //               passes it back to the calling Python process in a
00448 //               sensible way.
00449 ////////////////////////////////////////////////////////////////////
00450 void Thread::
00451 handle_python_exception() {
00452   /*
00453   PyObject *exc, *val, *tb;
00454   PyErr_Fetch(&exc, &val, &tb);
00455 
00456   ostringstream strm;
00457   strm << "\n";
00458 
00459   if (PyObject_HasAttrString(exc, "__name__")) {
00460     PyObject *exc_name = PyObject_GetAttrString(exc, "__name__");
00461     PyObject *exc_str = PyObject_Str(exc_name);
00462     strm << PyString_AsString(exc_str);
00463     Py_DECREF(exc_str);
00464     Py_DECREF(exc_name);
00465   } else {
00466     PyObject *exc_str = PyObject_Str(exc);
00467     strm << PyString_AsString(exc_str);
00468     Py_DECREF(exc_str);
00469   }
00470   Py_DECREF(exc);
00471 
00472   if (val != (PyObject *)NULL) {
00473     PyObject *val_str = PyObject_Str(val);
00474     strm << ": " << PyString_AsString(val_str);
00475     Py_DECREF(val_str);
00476     Py_DECREF(val);
00477   }
00478   if (tb != (PyObject *)NULL) {
00479     Py_DECREF(tb);
00480   }
00481 
00482   strm << "\nException occurred within thread " << get_name();
00483   string message = strm.str();
00484   nout << message << "\n";
00485 
00486   nassert_raise(message);
00487   */
00488 
00489   thread_cat.error()
00490     << "Exception occurred within " << *this << "\n";
00491 
00492   // Now attempt to force the main thread to the head of the ready
00493   // queue, so it will be the one to receive the above assertion.
00494   // This mainly only has an effect if SIMPLE_THREADS is in use.
00495   Thread::get_main_thread()->preempt();
00496 }
00497 #endif  // HAVE_PYTHON
00498 
00499 ////////////////////////////////////////////////////////////////////
00500 //     Function: Thread::init_main_thread
00501 //       Access: Private, Static
00502 //  Description: Creates the Thread object that represents the main
00503 //               thread.
00504 ////////////////////////////////////////////////////////////////////
00505 void Thread::
00506 init_main_thread() {
00507   // There is a chance of mutual recursion at startup.  The count
00508   // variable here attempts to protect against that.
00509   static int count = 0;
00510   ++count;
00511   if (count == 1 && _main_thread == (Thread *)NULL) {
00512     _main_thread = new MainThread;
00513     _main_thread->ref();
00514   }
00515 }
00516 
00517 ////////////////////////////////////////////////////////////////////
00518 //     Function: Thread::init_external_thread
00519 //       Access: Private, Static
00520 //  Description: Creates the Thread object that represents all of the
00521 //               external threads.
00522 ////////////////////////////////////////////////////////////////////
00523 void Thread::
00524 init_external_thread() {
00525   if (_external_thread == (Thread *)NULL) {
00526     _external_thread = new ExternalThread;
00527     _external_thread->ref();
00528   }
00529 }
00530 
00531 ////////////////////////////////////////////////////////////////////
00532 //     Function: Thread::PStatsCallback::Destructor
00533 //       Access: Public, Virtual
00534 //  Description: Since this class is just an interface definition,
00535 //               there is no need to have a destructor.  However, we
00536 //               must have one anyway to stop gcc's annoying warning.
00537 ////////////////////////////////////////////////////////////////////
00538 Thread::PStatsCallback::
00539 ~PStatsCallback() {
00540 }
00541 
00542 ////////////////////////////////////////////////////////////////////
00543 //     Function: Thread::PStatsCallback::deactivate_hook
00544 //       Access: Public, Virtual
00545 //  Description: Called when the thread is deactivated (swapped for
00546 //               another running thread).  This is intended to provide
00547 //               a callback hook for PStats to assign time to
00548 //               individual threads properly, particularly in the
00549 //               SIMPLE_THREADS case.
00550 ////////////////////////////////////////////////////////////////////
00551 void Thread::PStatsCallback::
00552 deactivate_hook(Thread *) {
00553 }
00554 
00555 ////////////////////////////////////////////////////////////////////
00556 //     Function: Thread::PStatsCallback::activate_hook
00557 //       Access: Public, Virtual
00558 //  Description: Called when the thread is activated (resumes
00559 //               execution).  This is intended to provide a callback
00560 //               hook for PStats to assign time to individual threads
00561 //               properly, particularly in the SIMPLE_THREADS case.
00562 ////////////////////////////////////////////////////////////////////
00563 void Thread::PStatsCallback::
00564 activate_hook(Thread *) {
00565 }
 All Classes Functions Variables Enumerations