question about concurrent access to resources
eric.pouech at orange.fr
Fri Oct 2 14:49:03 CDT 2009
Joerg-Cyril.Hoehle at t-systems.com a écrit :
> I need some information about threads and callbacks.
> I already found out that:
> - SetEvent delivers "asynchronously" and can unblock threads
> WaitingForMultipleObjects. No callback is involved (which
> does not mean that the current thread cannot be preempted
> by another one awakening).
> Therefore, this seems strange:
> I mean, if you left it, anything can have happened in between
> (including close of the device).
> - Likewise, notifications (to either thread or window) deliver
> asynchronously as well, to a message queue. No callback is involved.
> - OTOH functions like waveOutReset will callback into the
> applications (via Un-/PrepareBuffer etc.).
> In this example, LeaveCriticalSecion seems necessary, because
> waveOutReset does everything on the caller's thread, which
> might cause a driver to be entered recursively.
> dwRet = waveOutReset(wma->hWave);
> HOWEVER, Critical sections can be re-entered by the same thread.
> They are no inner-thread protection. Why then leave it?
> Is the Critical section adequate at all? What else is useable?
> Is it allowed for an application to call waveOpen in one thread
> and then call waveOut, waveStart, waveAddBuffer etc. from another one?
> Is it allowed to mmioSeek/mmioRead from different threads using the
> same handle?
> Thanks for your help,
> Jörg Höhle
the best answer to all of these questions is: write some tests !
regarding the question 1/, yes it maybe that wma no longer refers to a
correct object. to handle properly you need to add ref counting to the
regarding item #3, it doesn't protect against reentrancy, it will allow
the current object to be accessible if another thread tries to use it
while the first thread is in the middle of a notification
MSDN documentation says:
> Applications should not call any system-defined functions from inside
> a callback function, except for *EnterCriticalSection*,
> *LeaveCriticalSection*, *midiOutLongMsg*, *midiOutShortMsg*,
> *OutputDebugString*, *PostMessage*, *PostThreadMessage*, *SetEvent*,
> *timeGetSystemTime*, *timeGetTime*, *timeKillEvent*, and
> *timeSetEvent*. Calling other wave functions will cause deadlock.
(but don't take every MSDN word for granted, write tests!!!)
so the code out of mciavi32 seems rather sane to me, as it will not
block access to the ressource while processing the callback, even if not
so globally, the functions must be multi-thread safe
and reentrancy requires some testing
"The problem with designing something completely foolproof is to underestimate the ingenuity of a complete idiot." (Douglas Adams)
More information about the wine-devel