34 #include <boost/format.hpp> 47 ThreadPrivate(T
const& t) : _init(t) {
48 int ret = pthread_key_create(&_key, del);
51 "Could not create key");
55 T* d =
reinterpret_cast<T*
>(pthread_getspecific(_key));
58 pthread_setspecific(_key, d);
67 static void del(
void* data) {
68 T* d =
reinterpret_cast<T*
>(data);
73 static ThreadPrivate<dafBase::Citizen::memId> perThreadId(1);
74 static ThreadPrivate<bool> perThreadPersistFlag(
false);
79 int ret = pthread_rwlock_init(&_lock, 0);
82 "Could not create Citizen lock");
86 int ret = pthread_rwlock_wrlock(&_lock);
89 "Could not acquire Citizen write lock");
93 int ret = pthread_rwlock_rdlock(&_lock);
94 if (ret == 0)
return true;
95 if (ret == EDEADLK)
return false;
97 "Could not acquire Citizen read lock");
100 int ret = pthread_rwlock_unlock(&_lock);
103 "Could not release Citizen lock");
108 pthread_rwlock_t _lock;
111 static RwLock citizenLock;
115 ReadGuard(RwLock& lock) : _lock(lock) {
116 _mustUnlock = _lock.rdlock();
119 if (_mustUnlock) _lock.unlock();
129 WriteGuard(RwLock& lock) : _lock(lock) {
161 memId cid = _nextMemIdAndIncrement();
162 WriteGuard guard(citizenLock);
163 if (_shouldPersistCitizens()) {
169 _newId += _newCallback(cid);
175 _sentinel(magicSentinel),
176 _CitizenId(_addCitizen(this)),
177 _typeName(type.
name()) {
188 WriteGuard guard(citizenLock);
197 bool corrupt =
false;
199 WriteGuard guard(citizenLock);
201 corrupt = nActive > 1 ||
215 volatile int dummy = 1;
235 return perThreadId.getRef();
240 return perThreadId.getRef()++;
255 WriteGuard guard(citizenLock);
271 if (startingMemId == 0) {
272 ReadGuard guard(citizenLock);
277 ReadGuard guard(citizenLock);
280 if (cur->first->_CitizenId >= startingMemId) {
294 ReadGuard guard(citizenLock);
299 citizen !=
end; ++citizen) {
300 if ((*citizen)->getId() >= startingMemId) {
301 stream << (*citizen)->repr() <<
"\n";
325 ReadGuard guard(citizenLock);
330 vec->
push_back(dynamic_cast<Citizen const*>(cur->first));
354 ReadGuard guard(citizenLock);
357 if (cur->first->_hasBeenCorrupted()) {
363 if (cur->first->_hasBeenCorrupted()) {
379 WriteGuard guard(citizenLock);
390 WriteGuard guard(citizenLock);
475 return perThreadPersistFlag.getRef();
unsigned long memId
Type of the block's ID.
std::string demangleType(std::string const _typeName)
dafBase::Citizen::memId defaultDeleteCallback(dafBase::Citizen const *ptr)
Default DeleteCallback.
table::Key< std::string > name
static int init()
Called once when the memory system is being initialised.
~PersistentCitizenScope()
dafBase::Citizen::memId defaultNewCallback(dafBase::Citizen::memId const cid)
Default callbacks.
Called once when the memory system is being initialised.
static memCallback setCorruptionCallback(memCallback func)
Set the CorruptionCallback function.
std::map< Citizen const *, CitizenInfo > table
Include files required for standard LSST Exception handling.
static table _activeCitizens
void markPersistent(void)
Mark a Citizen as persistent and not destroyed until process end.
static memId setNewCallbackId(memId id)
Call the NewCallback when block is allocated.
static memNewCallback setNewCallback(memNewCallback func)
Set the NewCallback function.
static bool & _shouldPersistCitizens()
Set the NewCallback function.
static bool hasBeenCorrupted()
Check all allocated blocks for corruption.
static memCallback _deleteCallback
std::string repr() const
Return a string representation of a Citizen.
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
static table _persistentCitizens
static memId setDeleteCallbackId(memId id)
Call the current DeleteCallback when block is deleted.
memId getId() const
Return the Citizen's ID.
#define LSST_EXCEPT(type,...)
Create an exception with a given type and message and optionally other arguments (dependent on the ty...
memId(* memNewCallback)(const memId cid)
A function used to register a callback.
Citizen(const std::type_info &)
bool _hasBeenCorrupted() const
Check for corruption Return true if the block is corrupted, but only after calling the corruptionCall...
static memCallback setDeleteCallback(memCallback func)
Set the DeleteCallback function.
memId(* memCallback)(const Citizen *ptr)
static memId _nextMemIdAndIncrement(void)
Return the memId and prepare for the next object to be allocated.
static memId _nextMemId(void)
Return the memId of the next object to be allocated.
Citizen is a class that should be among all LSST classes base classes, and handles basic memory manag...
static memCallback _corruptionCallback
dafBase::Citizen::memId defaultCorruptionCallback(dafBase::Citizen const *ptr)
Default CorruptionCallback.
static memId _addCitizen(Citizen const *c)
static memNewCallback _newCallback
static memId getNextMemId()
Return the memId of the next object to be allocated.
static const std::vector< const Citizen * > * census()
Return a (newly allocated) std::vector of active Citizens sorted by ID.