Aki,
if I understand your critical section well, you serialize all accesses to
the individual player thread. This may be ok for commands that return immediately,
e.g. STATUS, but the MCI knows commands that may take a long time,
in particular PLAY, RECORD and even SEEK.
Did you run a test like this:
CreateTask {
SetEvent started
MCICommand(MCI_PLAY, "av_file_that_takes_3_minutes.avi", MCI_WAIT);
}
Wait(started);
Repeat 10 times {
MCICommand(MCI_STATUS,MCI_POSITION);
printf
MCICommand(MCI_STATUS,MCI_MODE);
Printf
Sleep(2s);
}
Wait(thread);
I would expect all MCI commands "STATUS POSITION" etc. to work while another thread is busy playing a file synchronously (using MCI_WAIT).
Furthermore
+static LRESULT MCIQTZ_relayTaskMessage [...]
+ if (WaitForSingleObject(wma->task.done, INFINITE) == WAIT_OBJECT_0)
Are you sure it's ok to block the user thread like this? Shouldn't the code use a loop that also pumps the MS-Windows message queue and dispatches messages? E.g. there may be a need to dispatch REFRESH and PAINT messages?
Did you cross-check what MS-Windows does here?
On a related note, IIRC some wine devices use a more reliable approach to waiting:
WaitForMultiple(2 objects: [task.done, task.threadId], INFINITE);
That way, should the player crash or exit somehow, the main (user) task doesn't hang.
Regards,
Jörg Höhle