joerg-cyril.hoe...@t-systems.com a écrit :
Hi,
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:
LeaveCriticalSection(&wma->cs);
SetEvent(wma->hStopEvent);
EnterCriticalSection(&wma->cs);
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.
LeaveCriticalSection(&wma->cs);
dwRet = waveOutReset(wma->hWave);
EnterCriticalSection(&wma->cs);
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
object
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
100% necessary
so globally, the functions must be multi-thread safe
and reentrancy requires some testing
A+
--
Eric Pouech
"The problem with designing something completely foolproof is to underestimate the
ingenuity of a complete idiot." (Douglas Adams)