change API of MIDI::Port::drain() to include a maximum blocking time

This commit is contained in:
Paul Davis 2016-02-01 13:26:30 -05:00
parent d98021624f
commit 5153631d70
4 changed files with 9 additions and 5 deletions

View file

@ -58,7 +58,7 @@ class LIBARDOUR_API AsyncMIDIPort : public ARDOUR::MidiPort, public MIDI::Port {
int write (const MIDI::byte *msg, size_t msglen, MIDI::timestamp_t timestamp); int write (const MIDI::byte *msg, size_t msglen, MIDI::timestamp_t timestamp);
int read (MIDI::byte *buf, size_t bufsize); int read (MIDI::byte *buf, size_t bufsize);
/* waits for output to be cleared */ /* waits for output to be cleared */
void drain (int check_interval_usecs); void drain (int check_interval_usecs, int total_usecs_to_wait);
/* clears async request communication channel */ /* clears async request communication channel */
void clear () { void clear () {

View file

@ -168,7 +168,7 @@ AsyncMIDIPort::cycle_end (MIDI::pframes_t nframes)
* Cannot be called from a processing thread. * Cannot be called from a processing thread.
*/ */
void void
AsyncMIDIPort::drain (int check_interval_usecs) AsyncMIDIPort::drain (int check_interval_usecs, int total_usecs_to_wait)
{ {
RingBuffer< Evoral::Event<double> >::rw_vector vec = { { 0, 0 }, { 0, 0} }; RingBuffer< Evoral::Event<double> >::rw_vector vec = { { 0, 0 }, { 0, 0} };
@ -183,12 +183,16 @@ AsyncMIDIPort::drain (int check_interval_usecs)
return; return;
} }
while (1) { microseconds_t now = get_microseconds ();
microseconds_t end = now + total_usecs_to_wait;
while (now < end) {
output_fifo.get_write_vector (&vec); output_fifo.get_write_vector (&vec);
if (vec.len[0] + vec.len[1] >= output_fifo.bufsize() - 1) { if (vec.len[0] + vec.len[1] >= output_fifo.bufsize() - 1) {
break; break;
} }
Glib::usleep (check_interval_usecs); Glib::usleep (check_interval_usecs);
now = get_microseconds();
} }
} }

View file

@ -75,7 +75,7 @@ class LIBMIDIPP_API Port {
* executes any part of a JACK process callback (will * executes any part of a JACK process callback (will
* simply return immediately in that situation). * simply return immediately in that situation).
*/ */
virtual void drain (int /* check_interval_usecs */) {} virtual void drain (int /* check_interval_usecs */, int /* total_usecs_to_wait */) {}
/** Write a message to port. /** Write a message to port.
* @return true on success. * @return true on success.

View file

@ -99,7 +99,7 @@ SurfacePort::~SurfacePort()
} }
if (_async_out) { if (_async_out) {
_output_port->drain (10000); _output_port->drain (10000, 250000);
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("unregistering output port %1\n", _async_out->name())); DEBUG_TRACE (DEBUG::MackieControl, string_compose ("unregistering output port %1\n", _async_out->name()));
AudioEngine::instance()->unregister_port (_async_out); AudioEngine::instance()->unregister_port (_async_out);
_async_out.reset ((ARDOUR::Port*) 0); _async_out.reset ((ARDOUR::Port*) 0);