Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygen_debug.c
Go 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 stlp_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) 00056 inline bool _STLP_CALL stlp_in_range_aux(_Iterator1 __it, const _Iterator& __first, 00057 #else 00058 inline bool _STLP_CALL stlp_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 stlp_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(stlp_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(stlp_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 stlp_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 stlp_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 00200 #if defined(_STLP_WCE) && defined(_ARM_) 00201 // Note: This part is needed for compiling under Windows CE under ARM and correctly using 00202 // _STLP_DEBUG mode. This comes from a bug in the ARM compiler where checked iterators that 00203 // are passed by value are not copied over correctly. When __change_range_owner is called, 00204 // e.g. in std::list::splice() the wrong _M_owner field gets modified and the __first 00205 // iterator has the old _M_owner field, but was moved to the new __owned_list. Setting 00206 // the first iterator's _M_owner field fixes this. Ugly but works. 00207 __pos = __CONST_CAST(_Iterator*, &__first); 00208 __pos->_M_owner = __CONST_CAST(__owned_list*, __dst); 00209 #endif 00210 //_STLP_RELEASE_LOCK(__base->_M_lock) 00211 } 00212 00213 template <class _Iterator> 00214 void _STLP_CALL __change_ite_owner(const _Iterator& __it, 00215 const __owned_list* __dst) { 00216 if (__it._Owner() == __dst) 00217 return; 00218 00219 typedef __owned_link _L_type; 00220 // Check __stl_debug_engine<_Dummy>::_Swap_owners comments to see why there is no lock here 00221 //_STLP_ACQUIRE_LOCK(__base->_M_lock) 00222 __owned_list *__base = __CONST_CAST(__owned_list*, __it._Owner()); 00223 _L_type* __prev = &__base->_M_node; 00224 _L_type* __pos = __prev->_M_next; 00225 _L_type* __dst_prev = __CONST_CAST(_L_type*, &__dst->_M_node); 00226 00227 while (__pos != 0) { 00228 // this requires safe iterators to be derived from __owned_link 00229 if ((__pos != __STATIC_CAST(const _L_type*, &__it)) && 00230 (__STATIC_CAST(_Iterator*, __pos)->_M_iterator == __it._M_iterator)) { 00231 __pos->_M_owner = __CONST_CAST(__owned_list*, __dst); 00232 //remove __pos from __base: 00233 __prev->_M_next = __pos->_M_next; 00234 //add __pos to __dst: 00235 __pos->_M_next = __dst_prev->_M_next; 00236 __dst_prev->_M_next = __pos; 00237 } 00238 else { 00239 __prev = __pos; 00240 } 00241 __pos = __prev->_M_next; 00242 } 00243 //_STLP_RELEASE_LOCK(__base->_M_lock) 00244 } 00245 00246 _STLP_MOVE_TO_STD_NAMESPACE 00247 _STLP_END_NAMESPACE 00248 00249 #endif /* _STLP_DEBUG */ 00250 00251 #if defined (_STLP_EXPOSE_GLOBALS_IMPLEMENTATION) 00252 00253 # ifndef _STLP_INTERNAL_CSTDLIB 00254 # include <stl/_cstdlib.h> 00255 # endif 00256 00257 //========================================================== 00258 // .c section 00259 // owned_list non-inline methods and global functions 00260 //========================================================== 00261 00262 # if defined (_STLP_ASSERTIONS) 00263 00264 _STLP_BEGIN_NAMESPACE 00265 _STLP_MOVE_TO_PRIV_NAMESPACE 00266 00267 # if !defined (_STLP_STRING_LITERAL) 00268 # define _STLP_STRING_LITERAL(__x) __x 00269 # endif 00270 00271 # if defined (_STLP_USE_WIDE_INTERFACE) 00272 // note: WinCE needs this to format single-byte strings in __stl_debug_engine::_Message 00273 # define _STLP_PERCENT_S "%hs" 00274 # else 00275 # define _STLP_PERCENT_S "%s" 00276 # endif /* _STLP_USE_WIDE_INTERFACE */ 00277 00278 # define _STLP_MESSAGE_TABLE_BODY = { \ 00279 _STLP_STRING_LITERAL("\n" _STLP_PERCENT_S "(%d): STL error: " _STLP_PERCENT_S "\n"), \ 00280 _STLP_STRING_LITERAL(_STLP_PERCENT_S "(%d): STL assertion failure : " _STLP_PERCENT_S "\n" _STLP_ASSERT_MSG_TRAILER), \ 00281 _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), \ 00282 _STLP_STRING_LITERAL("Invalid argument to operation (see operation documentation)"), \ 00283 _STLP_STRING_LITERAL("Taking an iterator out of destroyed (or otherwise corrupted) container"), \ 00284 _STLP_STRING_LITERAL("Trying to extract an object out from empty container"),\ 00285 _STLP_STRING_LITERAL("Past-the-end iterator could not be erased"), \ 00286 _STLP_STRING_LITERAL("Index out of bounds"), \ 00287 _STLP_STRING_LITERAL("Container doesn't own the iterator"), \ 00288 _STLP_STRING_LITERAL("Container is owner of the iterator, but should not"), \ 00289 _STLP_STRING_LITERAL("Uninitialized or invalidated (by mutating operation) iterator used"), \ 00290 _STLP_STRING_LITERAL("Uninitialized or invalidated (by mutating operation) lefthand iterator in expression"), \ 00291 _STLP_STRING_LITERAL("Uninitialized or invalidated (by mutating operation) righthand iterator in expression"), \ 00292 _STLP_STRING_LITERAL("Iterators used in expression are from different owners"), \ 00293 _STLP_STRING_LITERAL("Iterator could not be dereferenced (past-the-end ?)"), \ 00294 _STLP_STRING_LITERAL("Range [first,last) is invalid"), \ 00295 _STLP_STRING_LITERAL("Iterator is not in range [first,last)"), \ 00296 _STLP_STRING_LITERAL("Range [first,last) is not in range [start,finish)"), \ 00297 _STLP_STRING_LITERAL("The advance would produce invalid iterator"), \ 00298 _STLP_STRING_LITERAL("Iterator is singular (advanced beyond the bounds ?)"), \ 00299 _STLP_STRING_LITERAL("Invalid strict weak ordering predicate, if pred(a, b) then we should have !pred(b, a)"), \ 00300 _STLP_STRING_LITERAL("Invalid equivalent predicate, if pred(a, b) then we should have pred(b, a)"), \ 00301 _STLP_STRING_LITERAL("Memory block deallocated twice"), \ 00302 _STLP_STRING_LITERAL("Deallocating a block that was never allocated"), \ 00303 _STLP_STRING_LITERAL("Deallocating a memory block allocated for another type"), \ 00304 _STLP_STRING_LITERAL("Size of block passed to deallocate() doesn't match block size"), \ 00305 _STLP_STRING_LITERAL("Pointer underrun - safety margin at front of memory block overwritten"), \ 00306 _STLP_STRING_LITERAL("Pointer overrrun - safety margin at back of memory block overwritten"), \ 00307 _STLP_STRING_LITERAL("Attempt to dereference null pointer returned by auto_ptr::get()"), \ 00308 _STLP_STRING_LITERAL("Memory allocation function returned a wrongly align memory block"), \ 00309 _STLP_STRING_LITERAL("Unknown problem") \ 00310 } 00311 00312 template <class _Dummy> 00313 const char* __stl_debug_engine<_Dummy>::_Message_table[_StlMsg_MAX] _STLP_MESSAGE_TABLE_BODY; 00314 00315 # undef _STLP_STRING_LITERAL 00316 # undef _STLP_PERCENT_S 00317 00318 _STLP_MOVE_TO_STD_NAMESPACE 00319 _STLP_END_NAMESPACE 00320 00321 # if !defined (_STLP_DEBUG_MESSAGE) 00322 # ifndef _STLP_INTERNAL_CSTDARG 00323 # include <stl/_cstdarg.h> 00324 # endif 00325 # ifndef _STLP_INTERNAL_CSTDIO 00326 # include <stl/_cstdio.h> 00327 # endif 00328 # if defined (_STLP_DEBUG_MODE_THROWS) && !defined (_STLP_RANGE_ERRORS_H) 00329 # include <stl/_range_errors.h> 00330 # endif 00331 00332 _STLP_BEGIN_NAMESPACE 00333 _STLP_MOVE_TO_PRIV_NAMESPACE 00334 00335 template <class _Dummy> 00336 void _STLP_CALL 00337 __stl_debug_engine<_Dummy>::_Message(const char * __format_str, ...) { 00338 STLPORT_CSTD::va_list __args; 00339 va_start( __args, __format_str ); 00340 00341 # if !defined (_STLP_DEBUG_MODE_THROWS) 00342 # if defined (_STLP_USE_WIDE_INTERFACE) 00343 TCHAR __buffer[512]; 00344 int _convert = strlen(__format_str) + 1; 00345 LPWSTR _lpw = (LPWSTR)alloca(_convert * sizeof(wchar_t)); 00346 _lpw[0] = '\0'; 00347 MultiByteToWideChar(GetACP(), 0, __format_str, -1, _lpw, _convert); 00348 wvsprintf(__buffer, _lpw, __args); 00349 _STLP_WINCE_TRACE(__buffer); 00350 # elif defined (_STLP_WIN32) && (defined(_STLP_MSVC) || defined (__ICL)) 00351 char __buffer [4096]; 00352 00353 # if !defined (_STLP_USE_SAFE_STRING_FUNCTIONS) 00354 vsnprintf(__buffer, _STLP_ARRAY_SIZE(__buffer), __format_str, __args); 00355 # else 00356 vsnprintf_s(__buffer, _STLP_ARRAY_SIZE(__buffer), _TRUNCATE, __format_str, __args); 00357 # endif 00358 00359 OutputDebugStringA(__buffer); 00360 00361 # elif defined (__amigaos__) 00362 STLPORT_CSTD::vfprintf(stderr, __format_str, (char *)__args); 00363 # else 00364 STLPORT_CSTD::vfprintf(stderr, __format_str, __args); 00365 # endif 00366 # else 00367 char __buffer[4096]; 00368 00369 # if defined (_STLP_USE_SAFE_STRING_FUNCTIONS) 00370 vsnprintf_s(__buffer, _STLP_ARRAY_SIZE(__buffer), _TRUNCATE, __format_str, __args); 00371 # elif defined (_STLP_WIN32) && (defined(_STLP_MSVC) || defined (__ICL)) 00372 vsnprintf(__buffer, _STLP_ARRAY_SIZE(__buffer), __format_str, __args); 00373 # else 00374 vsprintf(__buffer, __format_str, __args); 00375 # endif 00376 # endif 00377 00378 # ifdef _STLP_DEBUG_MESSAGE_POST 00379 _STLP_DEBUG_MESSAGE_POST 00380 # endif 00381 00382 va_end(__args); 00383 00384 # if defined (_STLP_DEBUG_MODE_THROWS) 00385 __stl_throw_runtime_error(__buffer); 00386 # endif 00387 } 00388 00389 _STLP_MOVE_TO_STD_NAMESPACE 00390 _STLP_END_NAMESPACE 00391 00392 # else 00393 _STLP_BEGIN_NAMESPACE 00394 _STLP_MOVE_TO_PRIV_NAMESPACE 00395 template <class _Dummy> 00396 void _STLP_CALL 00397 __stl_debug_engine<_Dummy>::_Message(const char * __format_str, ...) 00398 {} 00399 _STLP_MOVE_TO_STD_NAMESPACE 00400 _STLP_END_NAMESPACE 00401 # endif /* _STLP_DEBUG_MESSAGE */ 00402 00403 _STLP_BEGIN_NAMESPACE 00404 _STLP_MOVE_TO_PRIV_NAMESPACE 00405 00406 template <class _Dummy> 00407 void _STLP_CALL 00408 __stl_debug_engine<_Dummy>::_IndexedError(int __error_ind, const char* __f, int __l) { 00409 __stl_debug_message(_Message_table[_StlFormat_ERROR_RETURN], 00410 __f, __l, _Message_table[__error_ind]); 00411 } 00412 00413 template <class _Dummy> 00414 void _STLP_CALL 00415 __stl_debug_engine<_Dummy>::_VerboseAssert(const char* __expr, int __error_ind, const char* __f, int __l) { 00416 __stl_debug_message(_Message_table[_StlFormat_VERBOSE_ASSERTION_FAILURE], 00417 __f, __l, _Message_table[__error_ind], __f, __l, __expr); 00418 __stl_debug_terminate(); 00419 } 00420 00421 template <class _Dummy> 00422 void _STLP_CALL 00423 __stl_debug_engine<_Dummy>::_Assert(const char* __expr, const char* __f, int __l) { 00424 __stl_debug_message(_Message_table[_StlFormat_ASSERTION_FAILURE],__f, __l, __expr); 00425 __stl_debug_terminate(); 00426 } 00427 00428 // if exceptions are present, sends unique exception 00429 // if not, calls abort() to terminate 00430 template <class _Dummy> 00431 void _STLP_CALL 00432 __stl_debug_engine<_Dummy>::_Terminate() 00433 { _STLP_ABORT(); } 00434 00435 _STLP_MOVE_TO_STD_NAMESPACE 00436 _STLP_END_NAMESPACE 00437 00438 # endif /* _STLP_ASSERTIONS */ 00439 00440 # if defined (_STLP_DEBUG) 00441 00442 _STLP_BEGIN_NAMESPACE 00443 _STLP_MOVE_TO_PRIV_NAMESPACE 00444 00445 //========================================================== 00446 // owned_list non-inline methods 00447 //========================================================== 00448 00449 template <class _Dummy> 00450 void _STLP_CALL 00451 __stl_debug_engine<_Dummy>::_Invalidate_all(__owned_list* __l) { 00452 _STLP_ACQUIRE_LOCK(__l->_M_lock); 00453 _Stamp_all(__l, 0); 00454 __l->_M_node._M_next =0; 00455 _STLP_RELEASE_LOCK(__l->_M_lock); 00456 } 00457 00458 // boris : this is unasafe routine; should be used from within critical section only ! 00459 template <class _Dummy> 00460 void _STLP_CALL 00461 __stl_debug_engine<_Dummy>::_Stamp_all(__owned_list* __l, __owned_list* __o) { 00462 // crucial 00463 if (__l->_M_node._M_owner) { 00464 for (__owned_link* __pos = (__owned_link*)__l->_M_node._M_next; 00465 __pos != 0; __pos = (__owned_link*)__pos->_M_next) { 00466 _STLP_ASSERT(__pos->_Owner()== __l) 00467 __pos->_M_owner=__o; 00468 } 00469 } 00470 } 00471 00472 template <class _Dummy> 00473 void _STLP_CALL 00474 __stl_debug_engine<_Dummy>::_Verify(const __owned_list* __l) { 00475 _STLP_ACQUIRE_LOCK(__l->_M_lock); 00476 if (__l) { 00477 _STLP_ASSERT(__l->_M_node._Owner() != 0) 00478 for (__owned_link* __pos = (__owned_link*)__l->_M_node._M_next; 00479 __pos != 0; __pos = (__owned_link*)__pos->_M_next) { 00480 _STLP_ASSERT(__pos->_Owner()== __l) 00481 } 00482 } 00483 _STLP_RELEASE_LOCK(__l->_M_lock); 00484 } 00485 00486 template <class _Dummy> 00487 void _STLP_CALL 00488 __stl_debug_engine<_Dummy>::_Swap_owners(__owned_list& __x, __owned_list& __y) { 00489 /* 00490 * according to the standard : --no swap() function invalidates any references, 00491 * pointers, or iterators referring to the elements of the containers being swapped. 00492 */ 00493 00494 __owned_link* __tmp; 00495 00496 /* 00497 * boris : there is a deadlock potential situation here if we lock two containers sequentially. 00498 * As user is supposed to provide its own synchronization around swap() ( it is unsafe to do any container/iterator access 00499 * in parallel with swap()), we just do not use any locking at all -- that behaviour is closer to non-debug version 00500 */ 00501 00502 __tmp = __x._M_node._M_next; 00503 00504 _Stamp_all(&__x, &__y); 00505 _Stamp_all(&__y, &__x); 00506 00507 __x._M_node._M_next = __y._M_node._M_next; 00508 __y._M_node._M_next = __tmp; 00509 } 00510 00511 template <class _Dummy> 00512 void _STLP_CALL 00513 __stl_debug_engine<_Dummy>::_Set_owner(__owned_list& __src, __owned_list& __dst) { 00514 if (&__src == &__dst) 00515 return; 00516 00517 // Check __stl_debug_engine<_Dummy>::_Swap_owners comments to see why there is no lock here 00518 typedef __owned_link _L_type; 00519 _L_type* __prev = &__src._M_node; 00520 _L_type* __pos = __prev->_M_next; 00521 00522 while (__pos != 0) { 00523 __pos->_M_owner = &__dst; 00524 __prev = __pos; 00525 __pos = __prev->_M_next; 00526 } 00527 __prev->_M_next = __dst._M_node._M_next; 00528 __dst._M_node._M_next = __src._M_node._M_next; 00529 __src._M_node._M_next = 0; 00530 } 00531 00532 template <class _Dummy> 00533 void _STLP_CALL 00534 __stl_debug_engine<_Dummy>::_M_detach(__owned_list* __l, __owned_link* __c_node) { 00535 if (__l != 0) { 00536 00537 _STLP_VERBOSE_ASSERT(__l->_Owner()!=0, _StlMsg_INVALID_CONTAINER) 00538 00539 _STLP_ACQUIRE_LOCK(__l->_M_lock) 00540 // boris : re-test the condition in case someone else already deleted us 00541 if(__c_node->_M_owner != 0) { 00542 __owned_link* __prev, *__next; 00543 00544 for (__prev = &__l->_M_node; (__next = __prev->_M_next) != __c_node; 00545 __prev = __next) { 00546 _STLP_ASSERT(__next && __next->_Owner() == __l) 00547 } 00548 00549 __prev->_M_next = __c_node->_M_next; 00550 __c_node->_M_owner=0; 00551 } 00552 _STLP_RELEASE_LOCK(__l->_M_lock) 00553 } 00554 } 00555 00556 template <class _Dummy> 00557 void _STLP_CALL 00558 __stl_debug_engine<_Dummy>::_M_attach(__owned_list* __l, __owned_link* __c_node) { 00559 if (__l ==0) { 00560 (__c_node)->_M_owner = 0; 00561 } else { 00562 _STLP_VERBOSE_ASSERT(__l->_Owner()!=0, _StlMsg_INVALID_CONTAINER) 00563 _STLP_ACQUIRE_LOCK(__l->_M_lock) 00564 __c_node->_M_owner = __l; 00565 __c_node->_M_next = __l->_M_node._M_next; 00566 __l->_M_node._M_next = __c_node; 00567 _STLP_RELEASE_LOCK(__l->_M_lock) 00568 } 00569 } 00570 00571 template <class _Dummy> 00572 void* _STLP_CALL 00573 __stl_debug_engine<_Dummy>::_Get_container_ptr(const __owned_link* __l) { 00574 const __owned_list* __owner = __l->_Owner(); 00575 _STLP_VERBOSE_RETURN_0(__owner != 0, _StlMsg_INVALID_ITERATOR) 00576 void* __ret = __CONST_CAST(void*,__owner->_Owner()); 00577 _STLP_VERBOSE_RETURN_0(__ret !=0, _StlMsg_INVALID_CONTAINER) 00578 return __ret; 00579 } 00580 00581 template <class _Dummy> 00582 bool _STLP_CALL 00583 __stl_debug_engine<_Dummy>::_Check_same_owner(const __owned_link& __i1, 00584 const __owned_link& __i2) { 00585 _STLP_VERBOSE_RETURN(__i1._Valid(), _StlMsg_INVALID_LEFTHAND_ITERATOR) 00586 _STLP_VERBOSE_RETURN(__i2._Valid(), _StlMsg_INVALID_RIGHTHAND_ITERATOR) 00587 _STLP_VERBOSE_RETURN((__i1._Owner() == __i2._Owner()), _StlMsg_DIFFERENT_OWNERS) 00588 return true; 00589 } 00590 00591 template <class _Dummy> 00592 bool _STLP_CALL 00593 __stl_debug_engine<_Dummy>::_Check_same_or_null_owner(const __owned_link& __i1, 00594 const __owned_link& __i2) { 00595 _STLP_VERBOSE_RETURN(__i1._Owner() == __i2._Owner(), _StlMsg_DIFFERENT_OWNERS) 00596 return true; 00597 } 00598 00599 template <class _Dummy> 00600 bool _STLP_CALL 00601 __stl_debug_engine<_Dummy>::_Check_if_owner( const __owned_list * __l, const __owned_link& __it) { 00602 const __owned_list* __owner_ptr = __it._Owner(); 00603 _STLP_VERBOSE_RETURN(__owner_ptr != 0, _StlMsg_INVALID_ITERATOR) 00604 _STLP_VERBOSE_RETURN(__l == __owner_ptr, _StlMsg_NOT_OWNER) 00605 return true; 00606 } 00607 00608 template <class _Dummy> 00609 bool _STLP_CALL 00610 __stl_debug_engine<_Dummy>::_Check_if_not_owner( const __owned_list * __l, const __owned_link& __it) { 00611 const __owned_list* __owner_ptr = __it._Owner(); 00612 _STLP_VERBOSE_RETURN(__owner_ptr != 0, _StlMsg_INVALID_ITERATOR) 00613 _STLP_VERBOSE_RETURN(__l != __owner_ptr, _StlMsg_SHOULD_NOT_OWNER) 00614 return true; 00615 } 00616 00617 _STLP_MOVE_TO_STD_NAMESPACE 00618 _STLP_END_NAMESPACE 00619 00620 # endif /* _STLP_DEBUG */ 00621 00622 #endif /* if defined (EXPOSE_GLOBALS_IMPLEMENTATION) */ 00623 00624 #endif /* header guard */ 00625 00626 // Local Variables: 00627 // mode:C++ 00628 // End: Generated on Sun May 27 2012 04:29:49 for ReactOS by
1.7.6.1
|