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

Joerg-Cyril.Hoehle at Joerg-Cyril.Hoehle at
Tue Jun 2 07:04:48 CDT 2015


>However, recent Windows systems don't allow to call MCI commands from another thread.
Could you please elaborate? I understand the Co/UnCo issue, but what about other commands?
Wouldn't the thread invoking Co/UnCo remain strictly internal to winmm?

At the MCI string command level, all you see are "device" numbers and aliases, so
why shouldn't an app be allowed to send "status x position" from any thread in
the app's address space?

>Do you know the application which relies on this feature?
I rarely analyzed app's requirements. I usually proceed as follows:
read available documentation,
perform many tests, then
turn a meaningful subset of these into wine test format and
write driver code that makes Wine nearly undistinguishable from native.

As native behavior varies, I prefer to target the version that was
in use at the time when the driver was mostly used (by commercial apps/games).
For the MCI, this means MS-Windows 3.x + 9X/ME and early 2k/XP.
When you wade through forums, you'll notice that some VB programmers
still use the MCI nowadays, but I saw no complex use cases there. Yet
I'm biased, as I hardly investigated mciqtz usage and mostly cared
about mciwave+midi+cda so far.

>> E.g. there may be a need to dispatch REFRESH and PAINT messages?
>I didn't check Windows behavior at that point.
>IMHO, MCI code doesn't assume the Window message queue and shouldn't touch them. 
Pumping message queue is pure hypothesis on my side, but it would be
valuable to know for sure. I'm not familiar with MS-Windows messaging
at all. When I raised the question in wine-devel 2013, IIRC I got no response.

I'm unsure there could be no interaction with the message queue in mciavi
and mciqtz. After all, there are MCI_*_HWND command options.

Some other area in need of investigation is timing. When or how fast
does a function return? For instance, there are entries in bugzilla
related to the time it takes to close and reopen winmm.

On a related side, at what time are callbacks invoked (or quartz pins)?
Fortunately, the MCI knows no callbacks (lesson learned), but they may
raise their ugly head again via the MCI-Quartz bridge.

As many (old?) apps are single-threaded, so I was told, the duration
of function calls matters, allowing the app to return to its message
queue fast. The order of calls through pins matters too, alas.

For instance, I've wondered whether it would be valuable to send PLAY,
PAUSE and STOP asynchronously, so as to return to the caller fast.
The driver could still have internal logic that would let it accept
the next command only after the current one is processed, so it's
still strictly serial. IOW there's a pipe of length 1 in between.
The difference is that the caller app is free to do other things
for as long as it doesn't issue commands to fast in a row.
I've observed evidence of some async. behavior with at least one
of the MCI drivers (mcicda perhaps, or mcimidi, not sure any more):
not all errors that PLAY would meet were returned immediately upon
command invocation (IIRC there were a few corner cases along
PLAY FROM 100 to 100).
From an implementation POV, this requires some processing (error checking,
e.g. refuse PLAY FROM 100 TO 50) before sending the async. message,
and checking the rest in the async. driver. That's quite different from
your current "forward immediately" patch. But that's just an idea.

	Jörg Höhle

More information about the wine-devel mailing list