Panda3D

thread.h

00001 // Filename: thread.h
00002 // Created by:  cary (16Sep98)
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 #ifndef THREAD_H
00016 #define THREAD_H
00017 
00018 #include "pandabase.h"
00019 #include "namable.h"
00020 #include "typedReferenceCount.h"
00021 #include "pointerTo.h"
00022 #include "threadPriority.h"
00023 #include "threadImpl.h"
00024 #include "pnotify.h"
00025 #include "config_pipeline.h"
00026 
00027 #ifdef HAVE_PYTHON
00028 #undef _POSIX_C_SOURCE
00029 #include <Python.h>
00030 #endif  // HAVE_PYTHON
00031 
00032 class Mutex;
00033 class ReMutex;
00034 class MutexDebug;
00035 class ConditionVarDebug;
00036 class ConditionVarFullDebug;
00037 class AsyncTaskBase;
00038 
00039 ////////////////////////////////////////////////////////////////////
00040 //       Class : Thread
00041 // Description : A thread; that is, a lightweight process.  This is an
00042 //               abstract base class; to use it, you must subclass
00043 //               from it and redefine thread_main().
00044 //
00045 //               The thread itself will keep a reference count on the
00046 //               Thread object while it is running; when the thread
00047 //               returns from its root function, the Thread object
00048 //               will automatically be destructed if no other pointers
00049 //               are referencing it.
00050 ////////////////////////////////////////////////////////////////////
00051 class EXPCL_PANDA_PIPELINE Thread : public TypedReferenceCount, public Namable {
00052 protected:
00053   Thread(const string &name, const string &sync_name);
00054 
00055 PUBLISHED:
00056   virtual ~Thread();
00057 
00058 private:
00059   INLINE Thread(const Thread &copy);
00060   INLINE void operator = (const Thread &copy);
00061 
00062 protected:
00063   virtual void thread_main()=0;
00064 
00065 PUBLISHED:
00066   static PT(Thread) bind_thread(const string &name, const string &sync_name);
00067 
00068   INLINE const string &get_sync_name() const;
00069 
00070   INLINE int get_pstats_index() const;
00071   INLINE string get_unique_id() const;
00072 
00073   INLINE int get_pipeline_stage() const;
00074   void set_pipeline_stage(int pipeline_stage);
00075   INLINE void set_min_pipeline_stage(int min_pipeline_stage);
00076 
00077   INLINE static Thread *get_main_thread();
00078   INLINE static Thread *get_external_thread();
00079   INLINE static Thread *get_current_thread();
00080   INLINE static int get_current_pipeline_stage();
00081   INLINE static bool is_threading_supported();
00082   INLINE static bool is_true_threads();
00083   INLINE static bool is_simple_threads();
00084   BLOCKING INLINE static void sleep(double seconds);
00085 
00086   BLOCKING INLINE static void force_yield();
00087   BLOCKING INLINE static void consider_yield();
00088 
00089   virtual void output(ostream &out) const;
00090   void output_blocker(ostream &out) const;
00091   static void write_status(ostream &out);
00092 
00093   INLINE bool is_started() const;
00094   INLINE bool is_joinable() const;
00095 
00096   bool start(ThreadPriority priority, bool joinable);
00097   BLOCKING INLINE void join();
00098   INLINE void preempt();
00099 
00100 #ifdef HAVE_PYTHON
00101   void set_python_data(PyObject *python_data);
00102   PyObject *get_python_data() const;
00103 #endif
00104 
00105   INLINE AsyncTaskBase *get_current_task() const;
00106 
00107   INLINE static void prepare_for_exit();
00108 
00109 public:
00110   // This class allows integration with PStats, particularly in the
00111   // SIMPLE_THREADS case.
00112   class EXPCL_PANDA_PIPELINE PStatsCallback {
00113   public:
00114     virtual ~PStatsCallback();
00115     virtual void deactivate_hook(Thread *thread);
00116     virtual void activate_hook(Thread *thread);
00117   };
00118 
00119   INLINE void set_pstats_index(int pstats_index);
00120   INLINE void set_pstats_callback(PStatsCallback *pstats_callback);
00121   INLINE PStatsCallback *get_pstats_callback() const;
00122 
00123 #ifdef HAVE_PYTHON
00124   // Integration with Python.
00125   PyObject *call_python_func(PyObject *function, PyObject *args);
00126   void handle_python_exception();
00127 #endif  // HAVE_PYTHON
00128 
00129 private:
00130   static void init_main_thread();
00131   static void init_external_thread();
00132 
00133 protected:
00134   bool _started;
00135 
00136 private:
00137   string _sync_name;
00138   ThreadImpl _impl;
00139   int _pstats_index;
00140   int _pipeline_stage;
00141   PStatsCallback *_pstats_callback;
00142   bool _joinable;
00143   AsyncTaskBase *_current_task;
00144 
00145 #ifdef HAVE_PYTHON
00146   PyObject *_python_data;
00147 #endif
00148 
00149 #ifdef DEBUG_THREADS
00150   MutexDebug *_blocked_on_mutex;
00151   ConditionVarDebug *_waiting_on_cvar;
00152   ConditionVarFullDebug *_waiting_on_cvar_full;
00153 #endif  // DEBUG_THREADS
00154 
00155 private:
00156   static Thread *_main_thread;
00157   static Thread *_external_thread;
00158 
00159 public:
00160   static TypeHandle get_class_type() {
00161     return _type_handle;
00162   }
00163   static void init_type() {
00164     TypedReferenceCount::init_type();
00165     Namable::init_type(),
00166     register_type(_type_handle, "Thread",
00167                   TypedReferenceCount::get_class_type(),
00168                   Namable::get_class_type());
00169   }
00170   virtual TypeHandle get_type() const {
00171     return get_class_type();
00172   }
00173   virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
00174 
00175 private:
00176   static TypeHandle _type_handle;
00177 
00178   friend class MutexDebug;
00179   friend class ConditionVarDebug;
00180   friend class ConditionVarFullDebug;
00181 
00182   friend class ThreadDummyImpl;
00183   friend class ThreadWin32Impl;
00184   friend class ThreadPosixImpl;
00185   friend class ThreadSimpleImpl;
00186   friend class MainThread;
00187   friend class AsyncTaskBase;
00188 };
00189 
00190 INLINE ostream &operator << (ostream &out, const Thread &thread);
00191 
00192 #include "thread.I"
00193 
00194 #endif
 All Classes Functions Variables Enumerations