/home/ntakagi/work/STLport-5.1.5/stlport/stl/debug/_debug.cGo to the documentation of this file.00001 /* 00002 * 00003 * Copyright (c) 1997 00004 * Moscow Center for SPARC Technology 00005 * 00006 * Copyright (c) 1999 00007 * Boris Fomitchev 00008 * 00009 * This material is provided "as is", with absolutely no warranty expressed 00010 * or implied. Any use is at your own risk. 00011 * 00012 * Permission to use or copy this software for any purpose is hereby granted 00013 * without fee, provided the above notices are retained on all copies. 00014 * Permission to modify the code and to distribute modified code is granted, 00015 * provided the above notices are retained, and a notice that the code was 00016 * modified is included with the above copyright notice. 00017 * 00018 */ 00019 00020 #ifndef _STLP_DEBUG_C 00021 #define _STLP_DEBUG_C 00022 00023 #if defined (_STLP_DEBUG) 00024 #if defined (_STLP_THREADS) 00025 # if !defined (_STLP_NEED_MUTABLE) 00026 # define _STLP_ACQUIRE_LOCK(_Lock) _Lock._M_acquire_lock(); 00027 # define _STLP_RELEASE_LOCK(_Lock) _Lock._M_release_lock(); 00028 # else 00029 # define _STLP_ACQUIRE_LOCK(_Lock) ((_STLP_mutex&)_Lock)._M_acquire_lock(); 00030 # define _STLP_RELEASE_LOCK(_Lock) ((_STLP_mutex&)_Lock)._M_release_lock(); 00031 # endif /* _STLP_NEED_MUTABLE */ 00032 #else 00033 # define _STLP_ACQUIRE_LOCK(_Lock) 00034 # define _STLP_RELEASE_LOCK(_Lock) 00035 #endif /* _STLP_THREADS */ 00036 00037 _STLP_BEGIN_NAMESPACE 00038 _STLP_MOVE_TO_PRIV_NAMESPACE 00039 00040 //========================================================== 00041 // global non-inline functions 00042 //========================================================== 00043 // [ i1, i2) 00044 #if !defined (__DMC__) 00045 template <class _Iterator> 00046 inline bool _STLP_CALL 00047 __in_range_aux(const _Iterator& __it, const _Iterator& __first, 00048 const _Iterator& __last, const random_access_iterator_tag &) { 00049 return ( __it >= __first && 00050 __it < __last); 00051 } 00052 #endif 00053 00054 template <class _Iterator1, class _Iterator> 00055 #if defined (_STLP_MSVC) && (_STLP_MSVC >= 1100) 00056 inline bool _STLP_CALL __in_range_aux(_Iterator1 __it, const _Iterator& __first, 00057 #else 00058 inline bool _STLP_CALL __in_range_aux(const _Iterator1& __it, const _Iterator& __first, 00059 #endif 00060 const _Iterator& __last, const forward_iterator_tag &) { 00061 _Iterator1 __i(__first); 00062 for (; __i != __last && __i != __it; ++__i); 00063 return (__i != __last); 00064 } 00065 00066 #if defined (_STLP_NONTEMPL_BASE_MATCH_BUG) 00067 template <class _Iterator1, class _Iterator> 00068 inline bool _STLP_CALL 00069 __in_range_aux(const _Iterator1& __it, const _Iterator& __first, 00070 const _Iterator& __last, const bidirectional_iterator_tag &) { 00071 _Iterator1 __i(__first); 00072 for (; __i != __last && __i != __it; ++__i); 00073 return (__i != __last); 00074 } 00075 #endif 00076 00077 template <class _Iterator> 00078 bool _STLP_CALL __check_range_aux(const _Iterator& __first, const _Iterator& __last, 00079 const __false_type& /*_IsIntegral*/) { 00080 _STLP_VERBOSE_RETURN(__valid_range(__first,__last), _StlMsg_INVALID_RANGE ) 00081 return true; 00082 } 00083 00084 template <class _Integral> 00085 bool _STLP_CALL __check_range_aux(_Integral /*__first*/, _Integral /*__last*/, 00086 const __true_type& /*_IsIntegral*/) 00087 { return true; } 00088 00089 template <class _Iterator> 00090 bool _STLP_CALL __check_range(const _Iterator& __first, const _Iterator& __last) { 00091 typedef typename _IsIntegral<_Iterator>::_Ret _Integral; 00092 return __check_range_aux(__first, __last, _Integral()); 00093 } 00094 00095 template <class _Iterator> 00096 bool _STLP_CALL __check_range(const _Iterator& __it, 00097 const _Iterator& __start, const _Iterator& __finish) { 00098 _STLP_VERBOSE_RETURN(__in_range(__it, __start, __finish), 00099 _StlMsg_NOT_IN_RANGE_1) 00100 return true; 00101 } 00102 00103 template <class _Iterator> 00104 bool _STLP_CALL __check_range(const _Iterator& __first, const _Iterator& __last, 00105 const _Iterator& __start, const _Iterator& __finish) { 00106 _STLP_VERBOSE_RETURN(__in_range(__first, __last, __start, __finish), 00107 _StlMsg_NOT_IN_RANGE_2) 00108 return true; 00109 } 00110 00111 template <class _Tp> 00112 bool _STLP_CALL __check_ptr_range(const _Tp* __first, const _Tp* __last) { 00113 _STLP_VERBOSE_RETURN((__first != 0 || __last == 0), _StlMsg_INVALID_ARGUMENT) 00114 _STLP_VERBOSE_RETURN(__valid_range(__first, __last, random_access_iterator_tag()), 00115 _StlMsg_INVALID_RANGE) 00116 return true; 00117 } 00118 00119 //=============================================================== 00120 template <class _Iterator> 00121 void _STLP_CALL __invalidate_range(const __owned_list* __base, 00122 const _Iterator& __first, 00123 const _Iterator& __last) { 00124 typedef __owned_link _L_type; 00125 _STLP_ACQUIRE_LOCK(__base->_M_lock) 00126 _L_type* __prev = __CONST_CAST(_L_type*, &__base->_M_node); 00127 _L_type* __pos = __prev->_M_next; 00128 00129 while (__pos != 0) { 00130 if (!(&__first == __STATIC_CAST(_Iterator*, __pos) || &__last == __STATIC_CAST(_Iterator*, __pos)) && 00131 __in_range_aux(__STATIC_CAST(_Iterator*, __pos)->_M_iterator, 00132 __first._M_iterator, __last._M_iterator, 00133 _STLP_ITERATOR_CATEGORY(__first, _Iterator))) { 00134 __pos->_M_owner = 0; 00135 __prev->_M_next = __pos->_M_next; 00136 } 00137 else { 00138 __prev = __pos; 00139 } 00140 __pos = __prev->_M_next; 00141 } 00142 _STLP_RELEASE_LOCK(__base->_M_lock) 00143 } 00144 00145 template <class _Iterator> 00146 void _STLP_CALL __invalidate_iterator(const __owned_list* __base, 00147 const _Iterator& __it) { 00148 typedef __owned_link _L_type; 00149 _STLP_ACQUIRE_LOCK(__base->_M_lock) 00150 _L_type* __prev = __CONST_CAST(_L_type*, &__base->_M_node); 00151 _L_type* __pos = __prev->_M_next; 00152 while (__pos != 0) { 00153 // this requires safe iterators to be derived from __owned_link 00154 if ((__pos != __STATIC_CAST(const _L_type*, &__it)) && 00155 (__STATIC_CAST(_Iterator*, __pos)->_M_iterator == __it._M_iterator)) { 00156 __pos->_M_owner = 0; 00157 __prev->_M_next = __pos->_M_next; 00158 } 00159 else { 00160 __prev = __pos; 00161 } 00162 __pos = __prev->_M_next; 00163 } 00164 _STLP_RELEASE_LOCK(__base->_M_lock) 00165 } 00166 00167 template <class _Iterator> 00168 void _STLP_CALL __change_range_owner(const _Iterator& __first, 00169 const _Iterator& __last, 00170 const __owned_list* __dst) { 00171 if (__first._Owner() == __dst) 00172 return; 00173 00174 typedef __owned_link _L_type; 00175 // Check __stl_debug_engine<_Dummy>::_Swap_owners comments to see why there is no lock here 00176 //_STLP_ACQUIRE_LOCK(__base->_M_lock) 00177 __owned_list *__base = __CONST_CAST(__owned_list*, __first._Owner()); 00178 _L_type* __src_prev = &__base->_M_node; 00179 _L_type* __pos = __src_prev->_M_next; 00180 _L_type* __dst_prev = __CONST_CAST(_L_type*, &__dst->_M_node); 00181 00182 while (__pos != 0) { 00183 if (!(&__first == __STATIC_CAST(_Iterator*, __pos) || &__last == __STATIC_CAST(_Iterator*, __pos)) && 00184 __in_range_aux(__STATIC_CAST(_Iterator*, __pos)->_M_iterator, 00185 __first._M_iterator, __last._M_iterator, 00186 _STLP_ITERATOR_CATEGORY(__first, _Iterator))) { 00187 __pos->_M_owner = __CONST_CAST(__owned_list*, __dst); 00188 //remove __pos from __base: 00189 __src_prev->_M_next = __pos->_M_next; 00190 //add __pos to __dst: 00191 __pos->_M_next = __dst_prev->_M_next; 00192 __dst_prev->_M_next = __pos; 00193 } 00194 else { 00195 __src_prev = __pos; 00196 } 00197 __pos = __src_prev->_M_next; 00198 } 00199 //_STLP_RELEASE_LOCK(__base->_M_lock) 00200 } 00201 00202 template <class _Iterator> 00203 void _STLP_CALL __change_ite_owner(const _Iterator& __it, 00204 const __owned_list* __dst) { 00205 if (__it._Owner() == __dst) 00206 return; 00207 00208 typedef __owned_link _L_type; 00209 // Check __stl_debug_engine<_Dummy>::_Swap_owners comments to see why there is no lock here 00210 //_STLP_ACQUIRE_LOCK(__base->_M_lock) 00211 __owned_list *__base = __CONST_CAST(__owned_list*, __it._Owner()); 00212 _L_type* __prev = &__base->_M_node; 00213 _L_type* __pos = __prev->_M_next; 00214 _L_type* __dst_prev = __CONST_CAST(_L_type*, &__dst->_M_node); 00215 00216 while (__pos != 0) { 00217 // this requires safe iterators to be derived from __owned_link 00218 if ((__pos != __STATIC_CAST(const _L_type*, &__it)) && 00219 (__STATIC_CAST(_Iterator*, __pos)->_M_iterator == __it._M_iterator)) { 00220 __pos->_M_owner = __CONST_CAST(__owned_list*, __dst); 00221 //remove __pos from __base: 00222 __prev->_M_next = __pos->_M_next; 00223 //add __pos to __dst: 00224 __pos->_M_next = __dst_prev->_M_next; 00225 __dst_prev->_M_next = __pos; 00226 } 00227 else { 00228 __prev = __pos; 00229 } 00230 __pos = __prev->_M_next; 00231 } 00232 //_STLP_RELEASE_LOCK(__base->_M_lock) 00233 } 00234 00235 _STLP_MOVE_TO_STD_NAMESPACE 00236 _STLP_END_NAMESPACE 00237 00238 #endif /* _STLP_DEBUG */ 00239 00240 #if defined (_STLP_EXPOSE_GLOBALS_IMPLEMENTATION) 00241 00242 # ifndef _STLP_INTERNAL_CSTDLIB 00243 # include <stl/_cstdlib.h> 00244 # endif 00245 00246 //========================================================== 00247 // .c section 00248 // owned_list non-inline methods and global functions 00249 //========================================================== 00250 00251 # if defined (_STLP_ASSERTIONS) 00252 00253 _STLP_BEGIN_NAMESPACE 00254 _STLP_MOVE_TO_PRIV_NAMESPACE 00255 00256 # if !defined (_STLP_STRING_LITERAL) 00257 # define _STLP_STRING_LITERAL(__x) __x 00258 # endif 00259 00260 # if defined (_STLP_USE_WIDE_INTERFACE) 00261 // note: WinCE needs this to format single-byte strings in __stl_debug_engine::_Message 00262 # define _STLP_PERCENT_S "%hs" 00263 # else 00264 # define _STLP_PERCENT_S "%s" 00265 # endif /* _STLP_USE_WIDE_INTERFACE */ 00266 00267 # define _STLP_MESSAGE_TABLE_BODY = { \ 00268 _STLP_STRING_LITERAL("\n" _STLP_PERCENT_S "(%d): STL error: " _STLP_PERCENT_S "\n"), \ 00269 _STLP_STRING_LITERAL(_STLP_PERCENT_S "(%d): STL assertion failure : " _STLP_PERCENT_S "\n" _STLP_ASSERT_MSG_TRAILER), \ 00270 _STLP_STRING_LITERAL("\n" _STLP_PERCENT_S "(%d): STL error : " _STLP_PERCENT_S "\n" _STLP_PERCENT_S "(%d): STL assertion failure: " _STLP_PERCENT_S " \n" _STLP_ASSERT_MSG_TRAILER), \ 00271 _STLP_STRING_LITERAL("Invalid argument to operation (see operation documentation)"), \ 00272 _STLP_STRING_LITERAL("Taking an iterator out of destroyed (or otherwise corrupted) container"), \ 00273 _STLP_STRING_LITERAL("Trying to extract an object out from empty container"),\ 00274 _STLP_STRING_LITERAL("Past-the-end iterator could not be erased"), \ 00275 _STLP_STRING_LITERAL("Index out of bounds"), \ 00276 _STLP_STRING_LITERAL("Container doesn't own the iterator"), \ 00277 _STLP_STRING_LITERAL("Container is owner of the iterator, but should not"), \ 00278 _STLP_STRING_LITERAL("Uninitialized or invalidated (by mutating operation) iterator used"), \ 00279 _STLP_STRING_LITERAL("Uninitialized or invalidated (by mutating operation) lefthand iterator in expression"), \ 00280 _STLP_STRING_LITERAL("Uninitialized or invalidated (by mutating operation) righthand iterator in expression"), \ 00281 _STLP_STRING_LITERAL("Iterators used in expression are from different owners"), \ 00282 _STLP_STRING_LITERAL("Iterator could not be dereferenced (past-the-end ?)"), \ 00283 _STLP_STRING_LITERAL("Range [first,last) is invalid"), \ 00284 _STLP_STRING_LITERAL("Iterator is not in range [first,last)"), \ 00285 _STLP_STRING_LITERAL("Range [first,last) is not in range [start,finish)"), \ 00286 _STLP_STRING_LITERAL("The advance would produce invalid iterator"), \ 00287 _STLP_STRING_LITERAL("Iterator is singular (advanced beyond the bounds ?)"), \ 00288 _STLP_STRING_LITERAL("Invalid strict weak ordering predicate, if pred(a, b) then we should have !pred(b, a)"), \ 00289 _STLP_STRING_LITERAL("Invalid equivalent predicate, if pred(a, b) then we should have pred(b, a)"), \ 00290 _STLP_STRING_LITERAL("Memory block deallocated twice"), \ 00291 _STLP_STRING_LITERAL("Deallocating a block that was never allocated"), \ 00292 _STLP_STRING_LITERAL("Deallocating a memory block allocated for another type"), \ 00293 _STLP_STRING_LITERAL("Size of block passed to deallocate() doesn't match block size"), \ 00294 _STLP_STRING_LITERAL("Pointer underrun - safety margin at front of memory block overwritten"), \ 00295 _STLP_STRING_LITERAL("Pointer overrrun - safety margin at back of memory block overwritten"), \ 00296 _STLP_STRING_LITERAL("Attempt to dereference null pointer returned by auto_ptr::get()"), \ 00297 _STLP_STRING_LITERAL("Memory allocation function returned a wrongly align memory block"), \ 00298 _STLP_STRING_LITERAL("Unknown problem") \ 00299 } 00300 00301 # if (_STLP_STATIC_TEMPLATE_DATA > 0) 00302 template <class _Dummy> 00303 const char* __stl_debug_engine<_Dummy>::_Message_table[_StlMsg_MAX] _STLP_MESSAGE_TABLE_BODY; 00304 00305 # if (defined (__CYGWIN__) || defined (__MINGW32__)) && \ 00306 defined (_STLP_USE_DYNAMIC_LIB) && !defined (__BUILDING_STLPORT) 00307 /* 00308 * Under cygwin, when STLport is used as a shared library, the id needs 00309 * to be specified as imported otherwise they will be duplicated in the 00310 * calling executable. 00311 */ 00312 _STLP_TEMPLATE_NULL 00313 _STLP_DECLSPEC const char* __stl_debug_engine<bool>::_Message_table[_StlMsg_MAX]; 00314 # endif 00315 00316 # else 00317 __DECLARE_INSTANCE(const char*, __stl_debug_engine<bool>::_Message_table[_StlMsg_MAX], 00318 _STLP_MESSAGE_TABLE_BODY); 00319 # endif 00320 00321 # undef _STLP_STRING_LITERAL 00322 # undef _STLP_PERCENT_S 00323 00324 _STLP_MOVE_TO_STD_NAMESPACE 00325 _STLP_END_NAMESPACE 00326 00327 // abort() 00328 # ifndef _STLP_INTERNAL_CSTDLIB 00329 # include <stl/_cstdlib.h> 00330 # endif 00331 00332 # if !defined (_STLP_DEBUG_MESSAGE) 00333 # ifndef _STLP_INTERNAL_CSTDARG 00334 # include <stl/_cstdarg.h> 00335 # endif 00336 # ifndef _STLP_INTERNAL_CSTDIO 00337 # include <stl/_cstdio.h> 00338 # endif 00339 # if defined (_STLP_DEBUG_MODE_THROWS) && !defined (_STLP_RANGE_ERRORS_H) 00340 # include <stl/_range_errors.h> 00341 # endif 00342 00343 _STLP_BEGIN_NAMESPACE 00344 _STLP_MOVE_TO_PRIV_NAMESPACE 00345 00346 template <class _Dummy> 00347 void _STLP_CALL 00348 __stl_debug_engine<_Dummy>::_Message(const char * __format_str, ...) { 00349 STLPORT_CSTD::va_list __args; 00350 va_start( __args, __format_str ); 00351 00352 # if !defined (_STLP_DEBUG_MODE_THROWS) 00353 # if defined (_STLP_USE_WIDE_INTERFACE) 00354 TCHAR __buffer[512]; 00355 int _convert = strlen(__format_str) + 1; 00356 LPWSTR _lpw = (LPWSTR)alloca(_convert * sizeof(wchar_t)); 00357 _lpw[0] = '\0'; 00358 MultiByteToWideChar(GetACP(), 0, __format_str, -1, _lpw, _convert); 00359 wvsprintf(__buffer, _lpw, __args); 00360 _STLP_WINCE_TRACE(__buffer); 00361 # elif defined (_STLP_WIN32) && (defined(_STLP_MSVC) || defined (__ICL)) 00362 char __buffer [4096]; 00363 00364 # if !defined (_STLP_USE_SAFE_STRING_FUNCTIONS) 00365 vsnprintf(__buffer, _STLP_ARRAY_SIZE(__buffer), __format_str, __args); 00366 # else 00367 vsnprintf_s(__buffer, _STLP_ARRAY_SIZE(__buffer), _TRUNCATE, __format_str, __args); 00368 # endif 00369 00370 OutputDebugStringA(__buffer); 00371 00372 # elif defined (__amigaos__) 00373 STLPORT_CSTD::vfprintf(stderr, __format_str, (char *)__args); 00374 # else 00375 STLPORT_CSTD::vfprintf(stderr, __format_str, __args); 00376 # endif 00377 # else 00378 char __buffer[4096]; 00379 00380 # if defined (_STLP_USE_SAFE_STRING_FUNCTIONS) 00381 vsnprintf_s(__buffer, _STLP_ARRAY_SIZE(__buffer), _TRUNCATE, __format_str, __args); 00382 # elif defined (_STLP_WIN32) && (defined(_STLP_MSVC) || defined (__ICL)) 00383 vsnprintf(__buffer, _STLP_ARRAY_SIZE(__buffer), __format_str, __args); 00384 # else 00385 vsprintf(__buffer, __format_str, __args); 00386 # endif 00387 # endif 00388 00389 # ifdef _STLP_DEBUG_MESSAGE_POST 00390 _STLP_DEBUG_MESSAGE_POST 00391 # endif 00392 00393 va_end(__args); 00394 00395 # if defined (_STLP_DEBUG_MODE_THROWS) 00396 __stl_throw_runtime_error(__buffer); 00397 # endif 00398 } 00399 00400 _STLP_MOVE_TO_STD_NAMESPACE 00401 _STLP_END_NAMESPACE 00402 00403 # else 00404 _STLP_BEGIN_NAMESPACE 00405 _STLP_MOVE_TO_PRIV_NAMESPACE 00406 template <class _Dummy> 00407 void _STLP_CALL 00408 __stl_debug_engine<_Dummy>::_Message(const char * __format_str, ...) 00409 {} 00410 _STLP_MOVE_TO_STD_NAMESPACE 00411 _STLP_END_NAMESPACE 00412 # endif /* _STLP_DEBUG_MESSAGE */ 00413 00414 _STLP_BEGIN_NAMESPACE 00415 _STLP_MOVE_TO_PRIV_NAMESPACE 00416 00417 template <class _Dummy> 00418 void _STLP_CALL 00419 __stl_debug_engine<_Dummy>::_IndexedError(int __error_ind, const char* __f, int __l) { 00420 __stl_debug_message(_Message_table[_StlFormat_ERROR_RETURN], 00421 __f, __l, _Message_table[__error_ind]); 00422 } 00423 00424 template <class _Dummy> 00425 void _STLP_CALL 00426 __stl_debug_engine<_Dummy>::_VerboseAssert(const char* __expr, int __error_ind, const char* __f, int __l) { 00427 __stl_debug_message(_Message_table[_StlFormat_VERBOSE_ASSERTION_FAILURE], 00428 __f, __l, _Message_table[__error_ind], __f, __l, __expr); 00429 __stl_debug_terminate(); 00430 } 00431 00432 template <class _Dummy> 00433 void _STLP_CALL 00434 __stl_debug_engine<_Dummy>::_Assert(const char* __expr, const char* __f, int __l) { 00435 __stl_debug_message(_Message_table[_StlFormat_ASSERTION_FAILURE],__f, __l, __expr); 00436 __stl_debug_terminate(); 00437 } 00438 00439 // if exceptions are present, sends unique exception 00440 // if not, calls abort() to terminate 00441 template <class _Dummy> 00442 void _STLP_CALL 00443 __stl_debug_engine<_Dummy>::_Terminate() 00444 { _STLP_ABORT(); } 00445 00446 _STLP_MOVE_TO_STD_NAMESPACE 00447 _STLP_END_NAMESPACE 00448 00449 # endif /* _STLP_ASSERTIONS */ 00450 00451 # if defined (_STLP_DEBUG) 00452 00453 _STLP_BEGIN_NAMESPACE 00454 _STLP_MOVE_TO_PRIV_NAMESPACE 00455 00456 //========================================================== 00457 // owned_list non-inline methods 00458 //========================================================== 00459 00460 template <class _Dummy> 00461 void _STLP_CALL 00462 __stl_debug_engine<_Dummy>::_Invalidate_all(__owned_list* __l) { 00463 _STLP_ACQUIRE_LOCK(__l->_M_lock); 00464 _Stamp_all(__l, 0); 00465 __l->_M_node._M_next =0; 00466 _STLP_RELEASE_LOCK(__l->_M_lock); 00467 } 00468 00469 // boris : this is unasafe routine; should be used from within critical section only ! 00470 template <class _Dummy> 00471 void _STLP_CALL 00472 __stl_debug_engine<_Dummy>::_Stamp_all(__owned_list* __l, __owned_list* __o) { 00473 // crucial 00474 if (__l->_M_node._M_owner) { 00475 for (__owned_link* __pos = (__owned_link*)__l->_M_node._M_next; 00476 __pos != 0; __pos = (__owned_link*)__pos->_M_next) { 00477 _STLP_ASSERT(__pos->_Owner()== __l) 00478 __pos->_M_owner=__o; 00479 } 00480 } 00481 } 00482 00483 template <class _Dummy> 00484 void _STLP_CALL 00485 __stl_debug_engine<_Dummy>::_Verify(const __owned_list* __l) { 00486 _STLP_ACQUIRE_LOCK(__l->_M_lock); 00487 if (__l) { 00488 _STLP_ASSERT(__l->_M_node._Owner() != 0) 00489 for (__owned_link* __pos = (__owned_link*)__l->_M_node._M_next; 00490 __pos != 0; __pos = (__owned_link*)__pos->_M_next) { 00491 _STLP_ASSERT(__pos->_Owner()== __l) 00492 } 00493 } 00494 _STLP_RELEASE_LOCK(__l->_M_lock); 00495 } 00496 00497 template <class _Dummy> 00498 void _STLP_CALL 00499 __stl_debug_engine<_Dummy>::_Swap_owners(__owned_list& __x, __owned_list& __y) { 00500 /* 00501 * according to the standard : --no swap() function invalidates any references, 00502 * pointers, or iterators referring to the elements of the containers being swapped. 00503 */ 00504 00505 __owned_link* __tmp; 00506 00507 /* 00508 * boris : there is a deadlock potential situation here if we lock two containers sequentially. 00509 * As user is supposed to provide its own synchronization around swap() ( it is unsafe to do any container/iterator access 00510 * in parallel with swap()), we just do not use any locking at all -- that behaviour is closer to non-debug version 00511 */ 00512 00513 __tmp = __x._M_node._M_next; 00514 00515 _Stamp_all(&__x, &__y); 00516 _Stamp_all(&__y, &__x); 00517 00518 __x._M_node._M_next = __y._M_node._M_next; 00519 __y._M_node._M_next = __tmp; 00520 } 00521 00522 template <class _Dummy> 00523 void _STLP_CALL 00524 __stl_debug_engine<_Dummy>::_Set_owner(__owned_list& __src, __owned_list& __dst) { 00525 if (&__src == &__dst) 00526 return; 00527 00528 // Check __stl_debug_engine<_Dummy>::_Swap_owners comments to see why there is no lock here 00529 typedef __owned_link _L_type; 00530 _L_type* __prev = &__src._M_node; 00531 _L_type* __pos = __prev->_M_next; 00532 00533 while (__pos != 0) { 00534 __pos->_M_owner = &__dst; 00535 __prev = __pos; 00536 __pos = __prev->_M_next; 00537 } 00538 __prev->_M_next = __dst._M_node._M_next; 00539 __dst._M_node._M_next = __src._M_node._M_next; 00540 __src._M_node._M_next = 0; 00541 } 00542 00543 template <class _Dummy> 00544 void _STLP_CALL 00545 __stl_debug_engine<_Dummy>::_M_detach(__owned_list* __l, __owned_link* __c_node) { 00546 if (__l != 0) { 00547 00548 _STLP_VERBOSE_ASSERT(__l->_Owner()!=0, _StlMsg_INVALID_CONTAINER) 00549 00550 _STLP_ACQUIRE_LOCK(__l->_M_lock) 00551 // boris : re-test the condition in case someone else already deleted us 00552 if(__c_node->_M_owner != 0) { 00553 __owned_link* __prev, *__next; 00554 00555 for (__prev = &__l->_M_node; (__next = __prev->_M_next) != __c_node; 00556 __prev = __next) { 00557 _STLP_ASSERT(__next && __next->_Owner() == __l) 00558 } 00559 00560 __prev->_M_next = __c_node->_M_next; 00561 __c_node->_M_owner=0; 00562 } 00563 _STLP_RELEASE_LOCK(__l->_M_lock) 00564 } 00565 } 00566 00567 template <class _Dummy> 00568 void _STLP_CALL 00569 __stl_debug_engine<_Dummy>::_M_attach(__owned_list* __l, __owned_link* __c_node) { 00570 if (__l ==0) { 00571 (__c_node)->_M_owner = 0; 00572 } else { 00573 _STLP_VERBOSE_ASSERT(__l->_Owner()!=0, _StlMsg_INVALID_CONTAINER) 00574 _STLP_ACQUIRE_LOCK(__l->_M_lock) 00575 __c_node->_M_owner = __l; 00576 __c_node->_M_next = __l->_M_node._M_next; 00577 __l->_M_node._M_next = __c_node; 00578 _STLP_RELEASE_LOCK(__l->_M_lock) 00579 } 00580 } 00581 00582 template <class _Dummy> 00583 void* _STLP_CALL 00584 __stl_debug_engine<_Dummy>::_Get_container_ptr(const __owned_link* __l) { 00585 const __owned_list* __owner = __l->_Owner(); 00586 _STLP_VERBOSE_RETURN_0(__owner != 0, _StlMsg_INVALID_ITERATOR) 00587 void* __ret = __CONST_CAST(void*,__owner->_Owner()); 00588 _STLP_VERBOSE_RETURN_0(__ret !=0, _StlMsg_INVALID_CONTAINER) 00589 return __ret; 00590 } 00591 00592 template <class _Dummy> 00593 bool _STLP_CALL 00594 __stl_debug_engine<_Dummy>::_Check_same_owner(const __owned_link& __i1, 00595 const __owned_link& __i2) { 00596 _STLP_VERBOSE_RETURN(__i1._Valid(), _StlMsg_INVALID_LEFTHAND_ITERATOR) 00597 _STLP_VERBOSE_RETURN(__i2._Valid(), _StlMsg_INVALID_RIGHTHAND_ITERATOR) 00598 _STLP_VERBOSE_RETURN((__i1._Owner() == __i2._Owner()), _StlMsg_DIFFERENT_OWNERS) 00599 return true; 00600 } 00601 00602 template <class _Dummy> 00603 bool _STLP_CALL 00604 __stl_debug_engine<_Dummy>::_Check_same_or_null_owner(const __owned_link& __i1, 00605 const __owned_link& __i2) { 00606 _STLP_VERBOSE_RETURN(__i1._Owner() == __i2._Owner(), _StlMsg_DIFFERENT_OWNERS) 00607 return true; 00608 } 00609 00610 template <class _Dummy> 00611 bool _STLP_CALL 00612 __stl_debug_engine<_Dummy>::_Check_if_owner( const __owned_list * __l, const __owned_link& __it) { 00613 const __owned_list* __owner_ptr = __it._Owner(); 00614 _STLP_VERBOSE_RETURN(__owner_ptr != 0, _StlMsg_INVALID_ITERATOR) 00615 _STLP_VERBOSE_RETURN(__l == __owner_ptr, _StlMsg_NOT_OWNER) 00616 return true; 00617 } 00618 00619 template <class _Dummy> 00620 bool _STLP_CALL 00621 __stl_debug_engine<_Dummy>::_Check_if_not_owner( const __owned_list * __l, const __owned_link& __it) { 00622 const __owned_list* __owner_ptr = __it._Owner(); 00623 _STLP_VERBOSE_RETURN(__owner_ptr != 0, _StlMsg_INVALID_ITERATOR) 00624 _STLP_VERBOSE_RETURN(__l != __owner_ptr, _StlMsg_SHOULD_NOT_OWNER) 00625 return true; 00626 } 00627 00628 _STLP_MOVE_TO_STD_NAMESPACE 00629 _STLP_END_NAMESPACE 00630 00631 # endif /* _STLP_DEBUG */ 00632 00633 #endif /* if defined (EXPOSE_GLOBALS_IMPLEMENTATION) */ 00634 00635 #endif /* header guard */ 00636 00637 // Local Variables: 00638 // mode:C++ 00639 // End:
Generated on Mon Mar 10 15:32:46 2008 by ![]() |