Mercurial > hg > svcore
view base/Scavenger.h @ 6:44bbf5793d84
* Rework handling of layer properties in file I/O -- we now get the individual
layers to load and save them rather than doing it via generic property lists
in the base class, so as to ensure we read and write meaningful values rather
than generic int values requiring conversion.
author | Chris Cannam |
---|---|
date | Thu, 19 Jan 2006 12:54:38 +0000 |
parents | d86891498eef |
children | b101cc2ae1ab |
line wrap: on
line source
/* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */ /* A waveform viewer and audio annotation editor. Chris Cannam, Queen Mary University of London, 2005-2006 This is experimental software. Not for distribution. */ /* This is a modified version of a source file from the Rosegarden MIDI and audio sequencer and notation editor. This file copyright 2000-2005 Chris Cannam. */ #ifndef _SCAVENGER_H_ #define _SCAVENGER_H_ #include "System.h" #include <vector> #include <sys/time.h> /** * A very simple class that facilitates running things like plugins * without locking, by collecting unwanted objects and deleting them * after a delay so as to be sure nobody's in the middle of using * them. Requires scavenge() to be called regularly from a non-RT * thread. * * This is currently not at all suitable for large numbers of objects * -- it's just a quick hack for use with things like plugins. */ template <typename T> class Scavenger { public: Scavenger(int sec = 2, int defaultObjectListSize = 200); /** * Call from an RT thread etc., to pass ownership of t to us. * Only one thread should be calling this on any given scavenger. */ void claim(T *t); /** * Call from a non-RT thread. * Only one thread should be calling this on any given scavenger. */ void scavenge(); protected: typedef std::pair<T *, int> ObjectTimePair; typedef std::vector<ObjectTimePair> ObjectTimeList; ObjectTimeList m_objects; int m_sec; unsigned int m_claimed; unsigned int m_scavenged; }; /** * A wrapper to permit arrays to be scavenged. */ template <typename T> class ScavengerArrayWrapper { public: ScavengerArrayWrapper(T *array) : m_array(array) { } ~ScavengerArrayWrapper() { delete[] m_array; } private: T *m_array; }; template <typename T> Scavenger<T>::Scavenger(int sec, int defaultObjectListSize) : m_objects(ObjectTimeList(defaultObjectListSize)), m_sec(sec), m_claimed(0), m_scavenged(0) { } template <typename T> void Scavenger<T>::claim(T *t) { // std::cerr << "Scavenger::claim(" << t << ")" << std::endl; struct timeval tv; (void)gettimeofday(&tv, 0); int sec = tv.tv_sec; for (size_t i = 0; i < m_objects.size(); ++i) { ObjectTimePair &pair = m_objects[i]; if (pair.first == 0) { pair.second = sec; pair.first = t; ++m_claimed; return; } } // Oh no -- run out of slots! Warn and discard something at // random (without deleting it -- it's probably safer to leak). for (size_t i = 0; i < m_objects.size(); ++i) { ObjectTimePair &pair = m_objects[i]; if (pair.first != 0) { pair.second = sec; pair.first = t; ++m_claimed; ++m_scavenged; } } } template <typename T> void Scavenger<T>::scavenge() { // std::cerr << "Scavenger::scavenge: scavenged " << m_scavenged << ", claimed " << m_claimed << std::endl; if (m_scavenged >= m_claimed) return; struct timeval tv; (void)gettimeofday(&tv, 0); int sec = tv.tv_sec; for (size_t i = 0; i < m_objects.size(); ++i) { ObjectTimePair &pair = m_objects[i]; if (pair.first != 0 && pair.second + m_sec < sec) { T *ot = pair.first; pair.first = 0; delete ot; ++m_scavenged; } } } #endif