+ Glib::Threads::Mutex m_lock;
+};
+
+class LIBPBD_API PerThreadPool;
+
+/** Management of a per-thread pool of data that is allocated by one thread and
+ * freed by one other thread. Not safe for use when there is more than 1
+ * reader and 1 writer.
+ *
+ * This is basically a wrapper around a thread-local storage instance of a
+ * ringbuffer, made safe for use in the case where multiple threads allocate
+ * from the ringbuffer and a single thread "frees" the allocations.
+ *
+ * Rather than using locks, each thread has its own ringbuffer (and associated
+ * data), and so it calls alloc(), passes a pointer to the result of the alloc
+ * to another thread, which later calls push() to "free" it.
+ */
+class LIBPBD_API CrossThreadPool : public Pool
+{
+ public:
+ CrossThreadPool (std::string n, unsigned long isize, unsigned long nitems, PerThreadPool *);
+
+ void* alloc ();
+ void push (void *);
+
+ PerThreadPool* parent () const {
+ return _parent;
+ }
+
+ bool empty ();
+
+ private:
+ RingBuffer<void*> pending;
+ PerThreadPool* _parent;
+};
+
+/** A class to manage per-thread pools of memory. One object of this class is instantiated,
+ * and then it is used to create per-thread pools for 1 or more threads as required.
+ */
+class LIBPBD_API PerThreadPool
+{
+ public:
+ PerThreadPool ();
+
+ const Glib::Threads::Private<CrossThreadPool>& key() const { return _key; }
+
+ void create_per_thread_pool (std::string name, unsigned long item_size, unsigned long nitems);
+ CrossThreadPool* per_thread_pool ();
+
+ void set_trash (RingBuffer<CrossThreadPool*>* t);
+ void add_to_trash (CrossThreadPool *);
+
+ private:
+ Glib::Threads::Private<CrossThreadPool> _key;
+ std::string _name;
+ unsigned long _item_size;
+ unsigned long _nitems;
+
+ /** mutex to protect either changes to the _trash variable, or writes to the RingBuffer */
+ Glib::Threads::Mutex _trash_mutex;
+ RingBuffer<CrossThreadPool*>* _trash;