1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
5 An audio time-stretching and pitch-shifting library.
6 Copyright 2007-2008 Chris Cannam.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version. See the file
12 COPYING included with this distribution for more information.
15 #ifndef _RUBBERBAND_SCAVENGER_H_
16 #define _RUBBERBAND_SCAVENGER_H_
29 namespace RubberBand {
32 * A very simple class that facilitates running things like plugins
33 * without locking, by collecting unwanted objects and deleting them
34 * after a delay so as to be sure nobody's in the middle of using
35 * them. Requires scavenge() to be called regularly from a non-RT
38 * This is currently not at all suitable for large numbers of objects
39 * -- it's just a quick hack for use with things like plugins.
46 Scavenger(int sec = 2, int defaultObjectListSize = 200);
50 * Call from an RT thread etc., to pass ownership of t to us.
51 * Only one thread should be calling this on any given scavenger.
56 * Call from a non-RT thread.
57 * Only one thread should be calling this on any given scavenger.
59 void scavenge(bool clearNow = false);
62 typedef std::pair<T *, int> ObjectTimePair;
63 typedef std::vector<ObjectTimePair> ObjectTimeList;
64 ObjectTimeList m_objects;
67 typedef std::list<T *> ObjectList;
72 void clearExcess(int);
74 unsigned int m_claimed;
75 unsigned int m_scavenged;
79 * A wrapper to permit arrays to be scavenged.
83 class ScavengerArrayWrapper
86 ScavengerArrayWrapper(T *array) : m_array(array) { }
87 ~ScavengerArrayWrapper() { delete[] m_array; }
95 Scavenger<T>::Scavenger(int sec, int defaultObjectListSize) :
96 m_objects(ObjectTimeList(defaultObjectListSize)),
103 template <typename T>
104 Scavenger<T>::~Scavenger()
106 if (m_scavenged < m_claimed) {
107 for (size_t i = 0; i < m_objects.size(); ++i) {
108 ObjectTimePair &pair = m_objects[i];
109 if (pair.first != 0) {
121 template <typename T>
123 Scavenger<T>::claim(T *t)
125 // std::cerr << "Scavenger::claim(" << t << ")" << std::endl;
128 (void)gettimeofday(&tv, 0);
131 for (size_t i = 0; i < m_objects.size(); ++i) {
132 ObjectTimePair &pair = m_objects[i];
133 if (pair.first == 0) {
141 std::cerr << "WARNING: Scavenger::claim(" << t << "): run out of slots, "
142 << "using non-RT-safe method" << std::endl;
146 template <typename T>
148 Scavenger<T>::scavenge(bool clearNow)
150 // std::cerr << "Scavenger::scavenge: scavenged " << m_scavenged << ", claimed " << m_claimed << std::endl;
152 if (m_scavenged >= m_claimed) return;
155 (void)gettimeofday(&tv, 0);
158 for (size_t i = 0; i < m_objects.size(); ++i) {
159 ObjectTimePair &pair = m_objects[i];
161 (pair.first != 0 && pair.second + m_sec < sec)) {
169 if (sec > m_lastExcess + m_sec) {
174 template <typename T>
176 Scavenger<T>::pushExcess(T *t)
178 m_excessMutex.lock();
179 m_excess.push_back(t);
181 (void)gettimeofday(&tv, 0);
182 m_lastExcess = tv.tv_sec;
183 m_excessMutex.unlock();
186 template <typename T>
188 Scavenger<T>::clearExcess(int sec)
190 m_excessMutex.lock();
191 for (typename ObjectList::iterator i = m_excess.begin();
192 i != m_excess.end(); ++i) {
197 m_excessMutex.unlock();