The midiOutShortMsg and midiOutLongMsg functions can be called by applications (and by device drivers) at interrupt time. Thus, the modMessage entry-point function in a MIDI output device driver can be accessed at interrupt time and must be written to be reentrant for the MODM_DATA and MODM_LONGDATA messages.
Note For internal MIDI synthesizer drivers, the interrupt-time reception of the MODM_DATA and MODM_LONGDATA messages has an additional consequence: The driver cannot access the disk at interrupt-time to load patch data if it receives a MIDI program-change request.
An example of the reentrancy situation is illustrated by an application that takes incoming MIDI events and sends them to a MIDI output port. The application's low-level callback function for MIDI input receives a MIDM_DATA message, accompanied by the incoming MIDI data. The callback function calls midiOutShortMsg to send the data to a MIDI output port. The modMessage entry-point function in the output port driver is called with a MODM_DATA message. This all happens at interrupt time. While modMessage is processing the MODM_DATA message, another MIDI event arrives at the input port, and the process starts again, with modMessage being reentered with another MODM_DATA message.
To handle being called at interrupt time, the modMessage entry-point function must follow these guidelines:
One way for synchronous drivers to be reentrant is to detect when modMessage is reentered and return a MIDIERR_NOTREADY error.
Note A good way for a synchronous driver to handle being reentered is for the driver to maintain a small buffer to hold data received when it's reentered, instead of returning MIDIERR_NOTREADY. Before the driver returns from the original modMessage call (the one that was reentered), it makes sure that all data in this buffer is sent to the hardware.