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)





Reply via email to