comparison base/Scavenger.h @ 0:da6937383da8

initial import
author Chris Cannam
date Tue, 10 Jan 2006 16:33:16 +0000
parents
children d86891498eef
comparison
equal deleted inserted replaced
-1:000000000000 0:da6937383da8
1 /* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 A waveform viewer and audio annotation editor.
5 Chris Cannam, Queen Mary University of London, 2005
6
7 This is experimental software. Not for distribution.
8 */
9
10 /*
11 This is a modified version of a source file from the
12 Rosegarden MIDI and audio sequencer and notation editor.
13 This file copyright 2000-2005 Chris Cannam.
14 */
15
16 #ifndef _SCAVENGER_H_
17 #define _SCAVENGER_H_
18
19 #include "System.h"
20
21 #include <vector>
22 #include <sys/time.h>
23
24 /**
25 * A very simple class that facilitates running things like plugins
26 * without locking, by collecting unwanted objects and deleting them
27 * after a delay so as to be sure nobody's in the middle of using
28 * them. Requires scavenge() to be called regularly from a non-RT
29 * thread.
30 *
31 * This is currently not at all suitable for large numbers of objects
32 * -- it's just a quick hack for use with things like plugins.
33 */
34
35 template <typename T>
36 class Scavenger
37 {
38 public:
39 Scavenger(int sec = 2, int defaultObjectListSize = 200);
40
41 /**
42 * Call from an RT thread etc., to pass ownership of t to us.
43 * Only one thread should be calling this on any given scavenger.
44 */
45 void claim(T *t);
46
47 /**
48 * Call from a non-RT thread.
49 * Only one thread should be calling this on any given scavenger.
50 */
51 void scavenge();
52
53 protected:
54 typedef std::pair<T *, int> ObjectTimePair;
55 typedef std::vector<ObjectTimePair> ObjectTimeList;
56 ObjectTimeList m_objects;
57 int m_sec;
58
59 unsigned int m_claimed;
60 unsigned int m_scavenged;
61 };
62
63 /**
64 * A wrapper to permit arrays to be scavenged.
65 */
66
67 template <typename T>
68 class ScavengerArrayWrapper
69 {
70 public:
71 ScavengerArrayWrapper(T *array) : m_array(array) { }
72 ~ScavengerArrayWrapper() { delete[] m_array; }
73
74 private:
75 T *m_array;
76 };
77
78
79 template <typename T>
80 Scavenger<T>::Scavenger(int sec, int defaultObjectListSize) :
81 m_objects(ObjectTimeList(defaultObjectListSize)),
82 m_sec(sec),
83 m_claimed(0),
84 m_scavenged(0)
85 {
86 }
87
88 template <typename T>
89 void
90 Scavenger<T>::claim(T *t)
91 {
92 // std::cerr << "Scavenger::claim(" << t << ")" << std::endl;
93
94 struct timeval tv;
95 (void)gettimeofday(&tv, 0);
96 int sec = tv.tv_sec;
97
98 for (size_t i = 0; i < m_objects.size(); ++i) {
99 ObjectTimePair &pair = m_objects[i];
100 if (pair.first == 0) {
101 pair.second = sec;
102 pair.first = t;
103 ++m_claimed;
104 return;
105 }
106 }
107
108 // Oh no -- run out of slots! Warn and discard something at
109 // random (without deleting it -- it's probably safer to leak).
110
111 for (size_t i = 0; i < m_objects.size(); ++i) {
112 ObjectTimePair &pair = m_objects[i];
113 if (pair.first != 0) {
114 pair.second = sec;
115 pair.first = t;
116 ++m_claimed;
117 ++m_scavenged;
118 }
119 }
120 }
121
122 template <typename T>
123 void
124 Scavenger<T>::scavenge()
125 {
126 // std::cerr << "Scavenger::scavenge: scavenged " << m_scavenged << ", claimed " << m_claimed << std::endl;
127
128 if (m_scavenged >= m_claimed) return;
129
130 struct timeval tv;
131 (void)gettimeofday(&tv, 0);
132 int sec = tv.tv_sec;
133
134 for (size_t i = 0; i < m_objects.size(); ++i) {
135 ObjectTimePair &pair = m_objects[i];
136 if (pair.first != 0 && pair.second + m_sec < sec) {
137 T *ot = pair.first;
138 pair.first = 0;
139 delete ot;
140 ++m_scavenged;
141 }
142 }
143 }
144
145 #endif