00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00018 #ifndef LIBCWD_PRIVATE_STRUCT_TSD_H
00019 #define LIBCWD_PRIVATE_STRUCT_TSD_H
00020
00021 #ifndef LIBCWD_CONFIG_H
00022 #include <libcwd/config.h>
00023 #endif
00024 #ifndef LIBCWD_PRIVATE_ASSERT_H
00025 #include <libcwd/private_assert.h>
00026 #endif
00027 #ifndef LIBCWD_PRIVATE_MUTEX_INSTANCES_H
00028 #include <libcwd/private_mutex_instances.h>
00029 #endif
00030 #ifndef LIBCW_CSTRING
00031 #define LIBCW_CSTRING
00032 #include <cstring>
00033 #endif
00034 #ifndef LIBCW_LIMITS_H
00035 #define LIBCW_LIMITS_H
00036 #include <limits.h>
00037 #endif
00038 #if LIBCWD_THREAD_SAFE
00039 #include <libcwd/private_mutex.h>
00040 #ifdef LIBCWD_HAVE_PTHREAD
00041 #ifndef LIBCW_PTHREAD_H
00042 #define LIBCW_PTHREAD_H
00043 #include <pthread.h>
00044 #endif
00045 #endif
00046 #endif
00047
00048 namespace libcwd {
00049 namespace _private_ {
00050 struct TSD_st;
00051 }
00052 }
00053
00054
00055
00056
00057
00058 #if LIBCWD_THREAD_SAFE
00059
00060 #define LIBCWD_TSD __libcwd_tsd // Optional `__libcwd_tsd' parameter (foo() or foo(__libcwd_tsd)).
00061 #define LIBCWD_COMMA_TSD , LIBCWD_TSD // Idem, but as second or higher parameter.
00062 #define LIBCWD_TSD_PARAM ::libcwd::_private_::TSD_st& __libcwd_tsd
00063
00064 #define LIBCWD_TSD_PARAM_UNUSED ::libcwd::_private_::TSD_st&
00065
00066 #define LIBCWD_COMMA_TSD_PARAM , LIBCWD_TSD_PARAM // Idem, but as second or higher parameter.
00067 #define LIBCWD_COMMA_TSD_PARAM_UNUSED , LIBCWD_TSD_PARAM_UNUSED
00068
00069 #define LIBCWD_TSD_INSTANCE ::libcwd::_private_::TSD_st::instance()
00070
00071 #define LIBCWD_COMMA_TSD_INSTANCE , LIBCWD_TSD_INSTANCE // Idem, but as second or higher parameter.
00072 #define LIBCWD_TSD_DECLARATION ::libcwd::_private_::TSD_st& __libcwd_tsd(::libcwd::_private_::TSD_st::instance())
00073
00074 #define LIBCWD_DO_TSD(debug_object) (*__libcwd_tsd.do_array[(debug_object).WNS_index])
00075
00076 #define LIBCWD_TSD_MEMBER_OFF (__libcwd_tsd.do_off_array[WNS_index])
00077
00078 #define LIBCWD_DO_TSD_MEMBER_OFF(debug_object) (__libcwd_tsd.do_off_array[(debug_object).WNS_index])
00079
00080
00081 #else // !LIBCWD_THREAD_SAFE
00082
00083 #define LIBCWD_TSD
00084 #define LIBCWD_COMMA_TSD
00085 #define LIBCWD_TSD_PARAM void
00086 #define LIBCWD_TSD_PARAM_UNUSED void
00087 #define LIBCWD_COMMA_TSD_PARAM
00088 #define LIBCWD_COMMA_TSD_PARAM_UNUSED
00089 #define LIBCWD_TSD_INSTANCE
00090 #define LIBCWD_COMMA_TSD_INSTANCE
00091 #define LIBCWD_TSD_DECLARATION
00092 #define LIBCWD_DO_TSD(debug_object) ((debug_object).tsd)
00093 #define LIBCWD_TSD_MEMBER_OFF (tsd._off)
00094 #define LIBCWD_DO_TSD_MEMBER_OFF(debug_object) ((debug_object).tsd._off)
00095
00096 #endif // !LIBCWD_THREAD_SAFE
00097
00098 #define LIBCWD_DO_TSD_MEMBER(debug_object, m) (LIBCWD_DO_TSD(debug_object).m)
00099 #define LIBCWD_TSD_MEMBER(m) LIBCWD_DO_TSD_MEMBER(*this, m)
00100
00101
00102 #ifndef LIBCWD_STRUCT_DEBUG_TSD_H
00103 #include <libcwd/struct_debug_tsd.h>
00104 #endif
00105 #if LIBCWD_THREAD_SAFE
00106 #ifndef LIBCWD_PRIVATE_THREAD_H
00107 #include <libcwd/private_thread.h>
00108 #endif
00109 #endif
00110
00111 namespace libcwd {
00112
00113 #if CWDEBUG_LOCATION
00114
00122 typedef unsigned short int location_format_t;
00123
00125 #endif
00126
00127 namespace _private_ {
00128
00129 extern int WST_initializing_TSD;
00130 class thread_ct;
00131
00132 struct TSD_st {
00133 public:
00134 #if CWDEBUG_ALLOC
00135 int internal;
00136 int library_call;
00137 int inside_malloc_or_free;
00138 int invisible;
00139 #endif // CWDEBUG_ALLOC
00140 #if CWDEBUG_LOCATION
00141 location_format_t format;
00142 #endif
00143 #if LIBCWD_THREAD_SAFE
00144 threadlist_t::iterator thread_iter;
00145 bool thread_iter_valid;
00146 thread_ct* target_thread;
00147 int terminating;
00148 bool pthread_lock_interface_is_locked;
00149 bool list_allocations_on_show_allthreads;
00150 int inside_free;
00151 #endif
00152 #if CWDEBUG_DEBUGM
00153 int marker;
00154 #if CWDEBUG_MAGIC
00155 int annotation;
00156 #endif
00157 #endif
00158 bool recursive_fatal;
00159 #if CWDEBUG_DEBUG
00160 bool recursive_assert;
00161 #endif
00162 #if CWDEBUG_DEBUGT
00163 int cancel_explicitely_deferred;
00164 int cancel_explicitely_disabled;
00165 int inside_critical_area;
00166 int cleanup_handler_installed;
00167 int internal_debugging_code;
00168 mutex_ct* waiting_for_mutex;
00169 int waiting_for_lock;
00170 int waiting_for_rdlock;
00171 int instance_rdlocked[instance_rdlocked_size];
00172 pthread_t rdlocked_by1[instance_rdlocked_size];
00173 pthread_t rdlocked_by2[instance_rdlocked_size];
00174 void const* rdlocked_from1[instance_rdlocked_size];
00175 void const* rdlocked_from2[instance_rdlocked_size];
00176 #endif
00177 #if LIBCWD_THREAD_SAFE
00178 pthread_t tid;
00179 pid_t pid;
00180 int do_off_array[LIBCWD_DO_MAX];
00181 debug_tsd_st* do_array[LIBCWD_DO_MAX];
00182 void cleanup_routine(void);
00183 int off_cnt_array[LIBCWD_DC_MAX];
00184 private:
00185 int tsd_destructor_count;
00186 #endif
00187
00188 public:
00189 void thread_destructed(void);
00190
00191 #if LIBCWD_THREAD_SAFE
00192
00193
00194 private:
00195 static TSD_st& S_create(int from_free);
00196 static pthread_key_t S_tsd_key;
00197 static pthread_once_t S_tsd_key_once;
00198 static void S_tsd_key_alloc(void);
00199 static void S_cleanup_routine(void* arg);
00200
00201 public:
00202 static TSD_st& instance(void);
00203 static TSD_st& instance_free(void);
00204 static void free_instance(TSD_st&);
00205 #endif // LIBCWD_THREAD_SAFE
00206 };
00207
00208
00209
00210
00211 #if !LIBCWD_THREAD_SAFE
00212
00213
00214
00215 extern TSD_st __libcwd_tsd;
00216 #else
00217 extern bool WST_tsd_key_created;
00218
00219 inline
00220 TSD_st& TSD_st::instance(void)
00221 {
00222 TSD_st* instance;
00223 if (!WST_tsd_key_created || !(instance = (TSD_st*)pthread_getspecific(S_tsd_key)))
00224 return S_create(0);
00225 return *instance;
00226 }
00227
00228
00229 inline
00230 TSD_st& TSD_st::instance_free(void)
00231 {
00232 TSD_st* instance;
00233 if (!WST_tsd_key_created || !(instance = (TSD_st*)pthread_getspecific(S_tsd_key)))
00234 return S_create(1);
00235 else
00236 instance->inside_free++;
00237 return *instance;
00238 }
00239 #endif
00240
00241 }
00242 }
00243
00244 #if !LIBCWD_THREAD_SAFE
00245
00246
00247 using ::libcwd::_private_::__libcwd_tsd;
00248 #endif
00249
00250 #endif // LIBCWD_PRIVATE_STRUCT_TSD_H