00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #ifndef W_ERROR_H
00054 #define W_ERROR_H
00055
00056 #include "w_defines.h"
00057
00058
00059
00060
00061 #ifdef __GNUG__
00062 #pragma interface
00063 #endif
00064
00065 #include "fc_error_enum_gen.h"
00066 #include "tls.h"
00067 #include "w_base.h"
00068
00069 #define USE_BLOCK_ALLOC_FOR_W_ERROR_T 0
00070 #if USE_BLOCK_ALLOC_FOR_W_ERROR_T
00071 DECLARE_TLS_SWATCHZ(w_error_alloc);
00072 #endif
00073
00074
00075
00076
00077
00078 struct w_error_info_t {
00079 w_base_t::uint4_t err_num;
00080 const char *errstr;
00081 };
00082
00083
00084
00085
00086
00087
00088 class w_error_t : public w_base_t {
00089 public:
00090 typedef w_error_info_t info_t;
00091
00092
00093
00094
00095
00096
00097
00098 typedef uint4_t err_num_t;
00099
00100
00101 const err_num_t err_num;
00102
00103 const char* const file;
00104 const uint4_t line;
00105 const int4_t sys_err_num;
00106
00107 w_error_t* next() { return _next; }
00108 w_error_t const* next() const { return _next; }
00109
00110 w_error_t& add_trace_info(
00111 const char* const filename,
00112 uint4_t line_num);
00113
00114 w_error_t& clear_more_info_msg();
00115 w_error_t& append_more_info_msg(const char* more_info);
00116 const char* get_more_info_msg() const;
00117 void claim();
00118 void verify_owner() const;
00119
00120 ostream &print_error(ostream &o) const;
00121
00122 #if USE_BLOCK_ALLOC_FOR_W_ERROR_T
00123 void operator delete(void* p);
00124 #endif
00125
00126 static w_error_t* make(
00127 const char* const filename,
00128 uint4_t line_num,
00129 err_num_t err_num,
00130 w_error_t* list = 0,
00131 const char* more_info = 0);
00132 static w_error_t* make(
00133 const char* const filename,
00134 uint4_t line_num,
00135 err_num_t err_num,
00136 uint4_t sys_err,
00137 w_error_t* list = 0,
00138 const char* more_info = 0);
00139
00140 static bool insert(
00141 const char *modulename,
00142 const info_t info[],
00143 uint4_t count);
00144
00145 static const w_error_t no_error_instance;
00146 static w_error_t* const no_error;
00147 static const char* error_string(err_num_t err_num);
00148 static const char* module_name(err_num_t err_num);
00149
00150 NORET ~w_error_t();
00151
00152 private:
00153 enum { max_range = 10, max_trace = 10 };
00154
00155
00156 private:
00157 const char* more_info_msg;
00158
00159 friend class w_rc_t;
00160
00161 uint4_t _trace_cnt;
00162 w_error_t* _next;
00163 const char* _trace_file[max_trace];
00164 uint4_t _trace_line[max_trace];
00165 #ifdef SM_THREAD_SAFE_ERRORS
00166 pthread_t _owner;
00167 #endif
00168
00169 NORET w_error_t(
00170 const char* const filename,
00171 uint4_t line_num,
00172 err_num_t err_num,
00173 w_error_t* list,
00174 const char* more_info);
00175 NORET w_error_t(
00176 const char* const filename,
00177 uint4_t line_num,
00178 err_num_t err_num,
00179 uint4_t sys_err,
00180 w_error_t* list,
00181 const char* more_info);
00182
00183
00184 NORET w_error_t(const w_error_t&);
00185 w_error_t& operator=(const w_error_t&);
00186
00187 static const info_t* _range_start[max_range];
00188 static uint4_t _range_cnt[max_range];
00189 static const char * _range_name[max_range];
00190 static uint4_t _nreg;
00191
00192 static inline uint4_t classify(int err_num);
00193 public:
00194
00195 static const info_t error_info[];
00196 static ostream & print(ostream &out);
00197 private:
00198
00199 static void init_errorcodes();
00200
00201 };
00202
00203 extern ostream &operator<<(ostream &o, const w_error_t &obj);
00204
00205 #ifdef SM_THREAD_SAFE_ERRORS
00206 #include <pthread.h>
00207 #include <stdlib.h>
00208 inline void w_error_t::claim() {
00209 _owner = pthread_self();
00210 }
00211 inline void w_error_t::verify_owner() const {
00212 w_assert1(pthread_equal(_owner, pthread_self()));
00213 }
00214 #else
00215 inline void w_error_t::claim() { }
00216 inline void w_error_t::verify_owner() const { }
00217 #endif
00218
00219 inline NORET
00220 w_error_t::~w_error_t()
00221 {
00222 delete[] more_info_msg;
00223 more_info_msg = NULL;
00224 delete _next;
00225 }
00226
00227
00228
00229 #endif