00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
00041
00042
00043
00044
00045
00046
00047
00048
00049
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
00111
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
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