add RAII-style write protection while rendering MIDI playlist into RTMidiBuffer
This commit is contained in:
@@ -63,6 +63,7 @@ class LIBARDOUR_API RTMidiBuffer : public Evoral::EventSink<samplepos_t>
|
||||
};
|
||||
|
||||
private:
|
||||
friend struct WriteProtectRender;
|
||||
|
||||
struct Blob {
|
||||
uint32_t size;
|
||||
@@ -85,7 +86,17 @@ class LIBARDOUR_API RTMidiBuffer : public Evoral::EventSink<samplepos_t>
|
||||
uint32_t _pool_capacity;
|
||||
uint8_t* _pool;
|
||||
|
||||
mutable Glib::Threads::RWLock _lock;
|
||||
Glib::Threads::RWLock _lock;
|
||||
|
||||
public:
|
||||
class WriteProtectRender {
|
||||
public:
|
||||
WriteProtectRender (RTMidiBuffer& rtm) : lm (rtm._lock, Glib::Threads::NOT_LOCK) {}
|
||||
void acquire () { lm.acquire(); }
|
||||
|
||||
private:
|
||||
Glib::Threads::RWLock::WriterLock lm;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
||||
@@ -519,8 +519,12 @@ MidiPlaylist::render (RTMidiBuffer& dst, MidiChannelFilter* filter)
|
||||
Evoral::EventList<samplepos_t> evlist;
|
||||
Evoral::EventSink<samplepos_t>* tgt;
|
||||
|
||||
/* RAII */
|
||||
RTMidiBuffer::WriteProtectRender wpr (dst);
|
||||
|
||||
if (regs.size() == 1) {
|
||||
tgt = &dst;
|
||||
wpr.acquire ();
|
||||
} else {
|
||||
tgt = &evlist;
|
||||
}
|
||||
@@ -545,6 +549,9 @@ MidiPlaylist::render (RTMidiBuffer& dst, MidiChannelFilter* filter)
|
||||
evlist.sort (cmp);
|
||||
|
||||
/* Copy ordered events from event list to dst. */
|
||||
|
||||
wpr.acquire ();
|
||||
|
||||
for (Evoral::EventList<samplepos_t>::iterator e = evlist.begin(); e != evlist.end(); ++e) {
|
||||
Evoral::Event<samplepos_t>* ev (*e);
|
||||
dst.write (ev->time(), ev->event_type(), ev->size(), ev->buffer());
|
||||
@@ -552,6 +559,8 @@ MidiPlaylist::render (RTMidiBuffer& dst, MidiChannelFilter* filter)
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_TRACE (DEBUG::MidiPlaylistIO, "---- End MidiPlaylist::dump ----\n");
|
||||
|
||||
/* no need to release - RAII with WriteProtectRender takes care of it */
|
||||
|
||||
DEBUG_TRACE (DEBUG::MidiPlaylistIO, "---- End MidiPlaylist::dump ----\n");
|
||||
}
|
||||
|
||||
@@ -167,11 +167,15 @@ item_timestamp_earlier (ARDOUR::RTMidiBuffer::Item const & item, samplepos_t tim
|
||||
return item.timestamp < time;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint32_t
|
||||
RTMidiBuffer::read (MidiBuffer& dst, samplepos_t start, samplepos_t end, MidiStateTracker& tracker, samplecnt_t offset)
|
||||
{
|
||||
Glib::Threads::RWLock::ReaderLock lm (_lock, Glib::Threads::TRY_LOCK);
|
||||
|
||||
if (!lm.locked()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Item* iend = _data+_size;
|
||||
Item* item = lower_bound (_data, iend, start, item_timestamp_earlier);
|
||||
uint32_t count = 0;
|
||||
|
||||
Reference in New Issue
Block a user