else if ( WaitResult == WAIT_IO_COMPLETION )
{
SND_TRACE(L"SoundThread - Processing IO completion\n");
- /* TODO */
+ /* TODO? What do we do here? Stream stuff? */
}
else
{
}
+ 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,
/* 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,
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;
}
+