mciqtz32: Guarantees that CoInitialize and CoUninitialize run on the same thread.

Joerg-Cyril.Hoehle at t-systems.com Joerg-Cyril.Hoehle at t-systems.com
Fri May 29 10:50:18 CDT 2015


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



More information about the wine-devel mailing list