Panda3D
|
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 ©); 00060 INLINE void operator = (const Thread ©); 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