Closing of wave output devices is functional and terminates the sound thread
[reactos.git] / reactos / lib / drivers / sound / mmebuddy / thread.c
index cc8ae7e..625cf96 100644 (file)
@@ -56,7 +56,7 @@ SoundThreadMain(
         else if ( WaitResult == WAIT_IO_COMPLETION )
         {
             SND_TRACE(L"SoundThread - Processing IO completion\n");
-            /* TODO */
+            /* TODO? What do we do here? Stream stuff? */
         }
         else
         {
@@ -66,9 +66,95 @@ SoundThreadMain(
 
     }
 
+    SND_TRACE(L"Sound thread terminated\n");
+
     return 0;
 }
 
+MMRESULT
+CallSoundThread(
+    IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
+    IN  SOUND_THREAD_REQUEST_HANDLER RequestHandler,
+    IN  PVOID Parameter OPTIONAL)
+{
+    PSOUND_THREAD Thread;
+
+    VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );
+    VALIDATE_MMSYS_PARAMETER( RequestHandler );
+
+    Thread = SoundDeviceInstance->Thread;
+
+    SND_TRACE(L"Waiting for READY event\n");
+    WaitForSingleObject(Thread->Events.Ready, INFINITE);
+
+    Thread->Request.Result = MMSYSERR_NOTSUPPORTED;
+    Thread->Request.Handler = RequestHandler;
+    Thread->Request.SoundDeviceInstance = SoundDeviceInstance;
+    Thread->Request.Parameter = Parameter;
+
+    /* Notify the thread it has work to do */
+    SND_TRACE(L"Setting REQUEST event\n");
+    SetEvent(Thread->Events.Request);
+
+    /* Wait for the work to be done */
+    SND_TRACE(L"Waiting for DONE event\n");
+    WaitForSingleObject(Thread->Events.Done, INFINITE);
+
+    return Thread->Request.Result;
+}
+
+
+MMRESULT
+SoundThreadTerminator(
+    IN  PSOUND_DEVICE_INSTANCE Instance,
+    IN  PVOID Parameter)
+{
+    PSOUND_THREAD Thread = (PSOUND_THREAD) Parameter;
+
+    SND_TRACE(L"Sound thread terminator routine called\n");
+    SND_ASSERT( Thread );
+
+    Thread->Running = FALSE;
+
+    return MMSYSERR_NOERROR;
+}
+
+MMRESULT
+TerminateSoundThread(
+    IN  PSOUND_THREAD Thread)
+{
+    DWORD WaitResult;
+
+    SND_ASSERT( Thread );
+
+    SND_TRACE(L"Waiting for READY event\n");
+    WaitForSingleObject(Thread->Events.Ready, INFINITE);
+
+    Thread->Request.Result = MMSYSERR_NOTSUPPORTED;
+    Thread->Request.Handler = SoundThreadTerminator;
+    Thread->Request.SoundDeviceInstance = NULL;
+    Thread->Request.Parameter = (PVOID) Thread;
+
+    /* Notify the thread it has work to do */
+    SND_TRACE(L"Setting REQUEST event\n");
+    SetEvent(Thread->Events.Request);
+
+    /* Wait for the work to be done */
+    SND_TRACE(L"Waiting for DONE event\n");
+    WaitForSingleObject(Thread->Events.Done, INFINITE);
+
+    /* Wait for the thread to actually end */
+    WaitResult = WaitForSingleObject(Thread->Handle, INFINITE);
+    SND_ASSERT( WaitResult == WAIT_OBJECT_0 );
+
+    /* Close the thread and invalidate the handle */
+    CloseHandle(Thread->Handle);    /* Is this needed? */
+    Thread->Handle = INVALID_HANDLE_VALUE;
+
+    return MMSYSERR_NOERROR;
+}
+
+
 MMRESULT
 CreateSoundThreadEvents(
     OUT HANDLE* ReadyEvent,
@@ -175,6 +261,7 @@ CreateSoundThread(
     /* Wake the thread up */
     if ( ResumeThread(NewThread->Handle) == -1 )
     {
+        SND_ERR(L"Failed to resume thread!\n");
         CloseHandle(NewThread->Handle);
         DestroySoundThreadEvents(NewThread->Events.Ready,
                                  NewThread->Events.Request,
@@ -192,36 +279,30 @@ CreateSoundThread(
 MMRESULT
 DestroySoundThread(
     IN  PSOUND_THREAD Thread)
-{
-    /* TODO: Implement me! */
-    return MMSYSERR_NOTSUPPORTED;
-}
-
-MMRESULT
-CallSoundThread(
-    IN  PSOUND_THREAD Thread,
-    IN  SOUND_THREAD_REQUEST_HANDLER RequestHandler,
-    IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance OPTIONAL,
-    IN  PVOID Parameter OPTIONAL)
 {
     VALIDATE_MMSYS_PARAMETER( Thread );
-    VALIDATE_MMSYS_PARAMETER( RequestHandler );
+    SND_ASSERT( Thread->Handle != INVALID_HANDLE_VALUE );
 
-    SND_TRACE(L"Waiting for READY event\n");
-    WaitForSingleObject(Thread->Events.Ready, INFINITE);
+    SND_TRACE(L"Terminating sound thread\n");
 
-    Thread->Request.Result = MMSYSERR_NOTSUPPORTED;
-    Thread->Request.Handler = RequestHandler;
-    Thread->Request.SoundDeviceInstance = SoundDeviceInstance;
-    Thread->Request.Parameter = Parameter;
+    /* Tell the thread to terminate itself */
+    TerminateSoundThread(Thread);
 
-    /* Notify the thread it has work to do */
-    SND_TRACE(L"Setting REQUEST event\n");
-    SetEvent(Thread->Events.Request);
+    SND_TRACE(L"Sound thread terminated, performing cleanup of thread resources\n");
 
-    /* Wait for the work to be done */
-    SND_TRACE(L"Waiting for DONE event\n");
-    WaitForSingleObject(Thread->Events.Done, INFINITE);
+    CloseHandle(Thread->Handle);    /* Is this needed? */
+    Thread->Handle = INVALID_HANDLE_VALUE;
 
-    return Thread->Request.Result;
+    DestroySoundThreadEvents(Thread->Events.Ready,
+                             Thread->Events.Request,
+                             Thread->Events.Done);
+
+    /* Wipe and free the memory used for the thread */
+    ZeroMemory(Thread, sizeof(SOUND_THREAD));
+    FreeMemory(Thread);
+
+    SND_TRACE(L"Finished thread cleanup\n");
+
+    return MMSYSERR_NOERROR;
 }
+