/* * Copyright information and license terms for this software can be * found in the file LICENSE that is included with the distribution */ #if __cplusplus>=201103L #include #include #define epicsExportSharedSymbols #include namespace { typedef epicsGuard Guard; } namespace epics { namespace debug { // joins together a group of ptr_base instances // which all have the same dtor struct tracker { epicsMutex mutex; ptr_base::ref_set_t refs; }; void shared_ptr_base::track_new() { if(track) { Guard G(track->mutex); track->refs.insert(this); } snap_stack(); } // create new tracker if ptr!=nullptr, otherwise clear void shared_ptr_base::track_new(void* ptr) { track_clear(); if(ptr){ track.reset(new tracker); Guard G(track->mutex); track->refs.insert(this); } snap_stack(); } void shared_ptr_base::track_assign(const shared_ptr_base &o) { if(track!=o.track) { track_clear(); track = o.track; if(track) { Guard G(track->mutex); track->refs.insert(this); } snap_stack(); } } void shared_ptr_base::track_clear() { if(track) { Guard G(track->mutex); track->refs.erase(this); } track.reset(); #ifndef EXCEPT_USE_NONE m_depth = 0; #endif } void shared_ptr_base::swap(shared_ptr_base &o) { // we cheat a bit here to avoid lock order, and to lock only twice if(track) { Guard G(track->mutex); track->refs.insert(&o); track->refs.erase(this); } track.swap(o.track); if(track) { Guard G(track->mutex); track->refs.insert(this); track->refs.erase(&o); } //TODO: keep original somehow??? snap_stack(); o.snap_stack(); } void shared_ptr_base::snap_stack() { if(!track) { #ifndef EXCEPT_USE_NONE m_depth = 0; #endif return; } #if defined(EXCEPT_USE_BACKTRACE) { m_depth=backtrace(m_stack,EXCEPT_DEPTH); } #else {} #endif } void shared_ptr_base::show_stack(std::ostream& strm) const { strm<<"ptr "<mutex); for(auto ref : track->refs) { if(!self && ref==this) continue; strm<<'#'; ref->show_stack(strm); strm<<'\n'; } } } void ptr_base::spy_refs(ref_set_t &refs) const { if(track) { Guard G(track->mutex); refs.insert(track->refs.begin(), track->refs.end()); } } }} // namespace epics::debug #endif // __cplusplus>=201103L