ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.