MidiMessage and Multiple Threads

I’m working on an application built on JUCE making heavy use of MIDI and threads. 

Part of what I am trying to accomplish is to aggregate in coming MIDI messages from multiple inputs and send them to a single output. Additionally, distributing a single MIDI input to multiple MIDI outputs. It could be thought of as a MIDI input/output mixer with analysis of all of the MIDI data.

My questions are...

Given multiple MIDI inputs, is the incoming MIDI data guaranteed to be handled on the same thread?

Can I call  MidiOutput::sendMessageNow from multiple threads?

On a similar line of thought, I see that MidiMessage can allocate memory. I’m a little surprised to see this happening on the main MIDI input thread as it could cause issues.  Does anyone have insight to why this does NOT cause any performance problems?

 

Thanks so much for any insight.
Bob
 

Given multiple MIDI inputs, is the incoming MIDI data guaranteed to be handled on the same thread?

No. The choice of thread is entirely up to the OS and device driver, and although I've never actually looked at what happens in practice, I wouldn't be surprised if some drivers use a thread per MIDI device.

Can I call  MidiOutput::sendMessageNow from multiple threads?

Probably.. Again, this is device driver/OS specific, it depends whether the OS function that posts a message is thread-safe. I'd expect them to be safe, but wouldn't recommend that you assume so. In all my apps I use a single thread to post midi messages to a particular device, which is often the only way to do it because you need to time the messages anyway. If you have a more ad-hoc system where you need multiple threads to all send messages, I'd probably recommend you use your own mutex to be on the safe side.

And yes, if you create a MidiMessage for a large message like a sysex, then it has to allocate memory for it.. Obviously for normal 3-byte messages that doesn't happen. But when you have a data structure that can contain an arbitrarily large lump of data, if you can suggest a mechanism for handling that which doesn't involve allocation, I'd love to hear about it!