As a side project, I am implementing a MIDI matrix to interconnect a number of MIDI keyboards with sound sources. The key requirement here is to echo MIDI data received on an input port to a selected output port.
Having created the necessary P/Invoke declarations & wrappers, I notice that the Win32 MIDI documentation for MidiInProc states: "Applications should not call any multimedia functions from inside the callback function, as doing so can cause a deadlock".
Given that it is unsafe to call midiOutShortMsg from within a MidiInProc, my current solution is to write MIDI data to a queue and set an event. A worker thread waits on the event and calls midiOutShortMsg. The general idea is this:-
static void InputCallback( int hMidiIn, uint wMsg, uint dwInstance, uint dwParam1, uint dwParam2 )
{
if( wMsg == MM_MIM_DATA )
{
data.EnQueue( dwParam1 ); //data is a Queue<uint>
dataReady.Set(); //dataReady is AutoResetEvent
}
}
void ThreadProc
{
while( !_done )
{
dataReady.WaitOne();
midiOutShortMsg( hMidiOut, data.DeQueue() );
}
}
However, whilst this has been working fine in testing, there appears to be a window of opportunity between the call to dataReady.Set() and InputCallBack returning during which preemption could allow the worker thread to call midiOutShortMsg (albeit in another thread).
Is this approach safe?