[ros-diffs] [silverblade] 34315: Sound worker request dispatcher thread partially implemented, along with routines for starting/stopping the thread and submitting requests. This allows wavethread (and, in future, midithread) to just get on with the required work and leave thread handling to something else. Also added macros to simplify allocation of memory for structures and wide strings.

silverblade at svn.reactos.org silverblade at svn.reactos.org
Sun Jul 6 01:23:51 CEST 2008


Author: silverblade
Date: Sat Jul  5 18:23:50 2008
New Revision: 34315

URL: http://svn.reactos.org/svn/reactos?rev=34315&view=rev
Log:
Sound worker request dispatcher thread partially implemented, along with
routines for starting/stopping the thread and submitting requests. This
allows wavethread (and, in future, midithread) to just get on with the
required work and leave thread handling to something else.

Also added macros to simplify allocation of memory for structures and wide strings.


Modified:
    branches/silverblade-audio/include/reactos/libs/sound/mmebuddy.h
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/devices.c
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/instances.c
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/nt4.c
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/testing.c
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/thread.c
    branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/wavethread.c

Modified: branches/silverblade-audio/include/reactos/libs/sound/mmebuddy.h
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/include/reactos/libs/sound/mmebuddy.h?rev=34315&r1=34314&r2=34315&view=diff
==============================================================================
--- branches/silverblade-audio/include/reactos/libs/sound/mmebuddy.h [iso-8859-1] (original)
+++ branches/silverblade-audio/include/reactos/libs/sound/mmebuddy.h [iso-8859-1] Sat Jul  5 18:23:50 2008
@@ -14,6 +14,40 @@
 
 #ifndef ROS_AUDIO_MMEBUDDY_H
 #define ROS_AUDIO_MMEBUDDY_H
+
+/*
+    Hacky debug macro
+*/
+
+#define SOUND_DEBUG(x) \
+    MessageBox(0, x, L"Debug", MB_OK | MB_TASKMODAL);
+
+
+/*
+    Some memory allocation helper macros
+*/
+
+#define AllocateMemory(size) \
+    HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size)
+
+#define FreeMemory(ptr) \
+    HeapFree(GetProcessHeap(), 0, ptr)
+
+#define AllocateMemoryFor(thing) \
+    (thing*) AllocateMemory(sizeof(thing))
+
+#define StringLengthToBytes(chartype, string_length) \
+    ( ( string_length + 1 ) * sizeof(chartype) )
+
+#define AllocateWideString(string_length) \
+    (PWSTR) AllocateMemory(StringLengthToBytes(WCHAR, string_length))
+
+#define ZeroWideString(string) \
+    ZeroMemory(string, StringLengthToBytes(WCHAR, wcslen(string)))
+
+#define CopyWideString(dest, source) \
+    CopyMemory(dest, source, StringLengthToBytes(WCHAR, wcslen(source)))
+
 
 struct _SOUND_DEVICE;
 struct _SOUND_DEVICE_INSTANCE;
@@ -34,28 +68,34 @@
 
 
 /*
+    Used internally to shuttle data to/from the sound processing thread.
+*/
+typedef struct _THREAD_REQUEST
+{
+    struct _SOUND_DEVICE_INSTANCE* DeviceInstance;
+    DWORD RequestId;
+    PVOID Data;
+    MMRESULT Result;
+} THREAD_REQUEST, *PTHREAD_REQUEST;
+
+
+/*
     Thread helper operations
 */
-
-typedef MMRESULT (*SOUND_THREAD_OPERATION)(
+typedef MMRESULT (*SOUND_THREAD_REQUEST_HANDLER)(
     IN  struct _SOUND_DEVICE_INSTANCE* Instance,
+    IN  DWORD RequestId,
     IN  PVOID Data);
-
-typedef struct _THREAD_OPERATIONS
-{
-    struct _THREAD_OPERATIONS* Next;
-    DWORD Id;
-    SOUND_THREAD_OPERATION Operation;
-} THREAD_OPERATIONS, *PTHREAD_OPERATIONS;
 
 typedef struct _SOUND_THREAD
 {
     HANDLE Handle;
     BOOLEAN Running;
-    PTHREAD_OPERATIONS FirstOperation;
-    HANDLE KillEvent;
-    HANDLE RequestEvent;
-    HANDLE RequestCompletionEvent;
+    SOUND_THREAD_REQUEST_HANDLER RequestHandler;
+    HANDLE ReadyEvent;      /* Thread waiting for a request */
+    HANDLE RequestEvent;    /* Caller sending a request */
+    HANDLE DoneEvent;       /* Thread completed a request */
+    THREAD_REQUEST Request;
 } SOUND_THREAD, *PSOUND_THREAD;
 
 
@@ -289,11 +329,28 @@
 
 MMRESULT
 StartSoundThread(
-    IN  PSOUND_DEVICE_INSTANCE Instance);
+    IN  PSOUND_DEVICE_INSTANCE Instance,
+    IN  SOUND_THREAD_REQUEST_HANDLER RequestHandler);
 
 MMRESULT
 StopSoundThread(
     IN  PSOUND_DEVICE_INSTANCE Instance);
 
+MMRESULT
+CallSoundThread(
+    IN  PSOUND_DEVICE_INSTANCE Instance,
+    IN  DWORD RequestId,
+    IN  PVOID RequestData);
+
+
+
+MMRESULT
+StartWaveThread(
+    IN  PSOUND_DEVICE_INSTANCE Instance);
+
+MMRESULT
+StopWaveThread(
+    IN  PSOUND_DEVICE_INSTANCE Instance);
+
 
 #endif

Modified: branches/silverblade-audio/lib/drivers/sound/mmebuddy/devices.c
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/sound/mmebuddy/devices.c?rev=34315&r1=34314&r2=34315&view=diff
==============================================================================
--- branches/silverblade-audio/lib/drivers/sound/mmebuddy/devices.c [iso-8859-1] (original)
+++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/devices.c [iso-8859-1] Sat Jul  5 18:23:50 2008
@@ -131,7 +131,8 @@
         /* Save the next device pointer so we can reference it later */
         NextDevice = CurrentDevice->Next;
 
-        HeapFree(GetProcessHeap(), 0, CurrentDevice);
+        FreeMemory(CurrentDevice);
+        /*HeapFree(GetProcessHeap(), 0, CurrentDevice);*/
         CurrentDevice = NextDevice;
     }
 
@@ -157,7 +158,6 @@
     LPWSTR DevicePath)
 {
     PSOUND_DEVICE NewDevice;
-    ULONG DevicePathSize = 0;
     UCHAR TypeIndex;
 
     DPRINT("Adding a sound device to list %d\n", DeviceType);
@@ -169,31 +169,37 @@
 
     TypeIndex = DeviceType - MIN_SOUND_DEVICE_TYPE;
 
+    NewDevice = AllocateMemoryFor(SOUND_DEVICE);
+/*
     NewDevice = (PSOUND_DEVICE)
         HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SOUND_DEVICE));
+*/
 
     if ( ! NewDevice )
     {
         return FALSE;
     }
-
-    DevicePathSize = (wcslen(DevicePath) + 1) * sizeof(WCHAR);
 
     NewDevice->Next = NULL;
     NewDevice->FirstInstance = NULL;
     NewDevice->DeviceType = DeviceType;
     NewDevice->Handle = INVALID_HANDLE_VALUE;
 
+    NewDevice->DevicePath = AllocateWideString(wcslen(DevicePath));
+/*
     NewDevice->DevicePath = (LPWSTR)
         HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, DevicePathSize);
+*/
 
     if ( ! NewDevice->DevicePath )
     {
-        HeapFree(GetProcessHeap(), 0, NewDevice);
-        return FALSE;
-    }
-
-    CopyMemory(NewDevice->DevicePath, DevicePath, DevicePathSize);
+        FreeMemory(NewDevice);
+        /*HeapFree(GetProcessHeap(), 0, NewDevice);*/
+        return FALSE;
+    }
+
+    CopyWideString(NewDevice->DevicePath, DevicePath);
+    /*CopyMemory(NewDevice->DevicePath, DevicePath, DevicePathSize);*/
 
     /* Set up function table */
     InitSoundDeviceFunctionTable(NewDevice);
@@ -280,7 +286,9 @@
             }
 
             /* Free the memory associated with the device info */
-            HeapFree(GetProcessHeap(), 0, CurrentDevice);
+            FreeMemory(CurrentDevice->DevicePath);
+            FreeMemory(CurrentDevice);
+            /*HeapFree(GetProcessHeap(), 0, CurrentDevice);*/
             CurrentDevice = NULL;
 
             DPRINT("Removal succeeded\n");

Modified: branches/silverblade-audio/lib/drivers/sound/mmebuddy/instances.c
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/sound/mmebuddy/instances.c?rev=34315&r1=34314&r2=34315&view=diff
==============================================================================
--- branches/silverblade-audio/lib/drivers/sound/mmebuddy/instances.c [iso-8859-1] (original)
+++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/instances.c [iso-8859-1] Sat Jul  5 18:23:50 2008
@@ -36,10 +36,13 @@
     if ( ! Instance )
         return MMSYSERR_INVALPARAM;
 
+    NewInstance = AllocateMemoryFor(SOUND_DEVICE_INSTANCE);
+/*
     NewInstance = (PSOUND_DEVICE_INSTANCE)
         HeapAlloc(GetProcessHeap(),
                   HEAP_ZERO_MEMORY,
                   sizeof(SOUND_DEVICE_INSTANCE));
+*/
 
     if ( ! NewInstance )
         return MMSYSERR_NOMEM;
@@ -114,7 +117,8 @@
     }
 
     /* Kill it! */
-    HeapFree(GetProcessHeap(), 0, Instance);
+    FreeMemory(Instance);
+    /*HeapFree(GetProcessHeap(), 0, Instance);*/
 
     return MMSYSERR_NOTSUPPORTED;
 }

Modified: branches/silverblade-audio/lib/drivers/sound/mmebuddy/nt4.c
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/sound/mmebuddy/nt4.c?rev=34315&r1=34314&r2=34315&view=diff
==============================================================================
--- branches/silverblade-audio/lib/drivers/sound/mmebuddy/nt4.c [iso-8859-1] (original)
+++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/nt4.c [iso-8859-1] Sat Jul  5 18:23:50 2008
@@ -45,14 +45,15 @@
     /* Work out how long the string will be */
     KeyLength = wcslen(REG_SERVICES_KEY_NAME_U) + 1
               + wcslen(ServiceName) + 1
-              + wcslen(REG_PARAMETERS_KEY_NAME_U) + 1;
-
-    KeyLength *= sizeof(WCHAR);
+              + wcslen(REG_PARAMETERS_KEY_NAME_U);
 
     /* Allocate memory for the string */
+    ParametersKeyName = AllocateWideString(KeyLength);
+/*
     ParametersKeyName = (PWCHAR) HeapAlloc(GetProcessHeap(),
                                            HEAP_ZERO_MEMORY,
                                            KeyLength);
+*/
 
     if ( ! ParametersKeyName )
         return MMSYSERR_NOMEM;
@@ -74,11 +75,13 @@
                       KeyHandle) != ERROR_SUCCESS )
     {
         /* Couldn't open the key */
-        HeapFree(GetProcessHeap(), 0, ParametersKeyName);
+        FreeMemory(ParametersKeyName);
+        /*HeapFree(GetProcessHeap(), 0, ParametersKeyName);*/
         return MMSYSERR_ERROR;
     }
 
-    HeapFree(GetProcessHeap(), 0, ParametersKeyName);
+    FreeMemory(ParametersKeyName);
+    /*HeapFree(GetProcessHeap(), 0, ParametersKeyName);*/
 
     return MMSYSERR_NOERROR;
 }
@@ -93,7 +96,7 @@
     IN  DWORD DeviceIndex,
     OUT PHKEY KeyHandle)
 {
-    DWORD PathSize;
+    DWORD PathLength;
     PWCHAR RegPath;
 
     if ( ! ServiceName )
@@ -110,18 +113,19 @@
                 Parameters\
                     Device123\
     */
-    PathSize = wcslen(REG_SERVICES_KEY_NAME_U) + 1
-             + wcslen(ServiceName) + 1
-             + wcslen(REG_PARAMETERS_KEY_NAME_U) + 1
-             + wcslen(REG_DEVICE_KEY_NAME_U)
-             + GetDigitCount(DeviceIndex) + 1;
-
-    PathSize *= sizeof(WCHAR);
+    PathLength = wcslen(REG_SERVICES_KEY_NAME_U) + 1
+               + wcslen(ServiceName) + 1
+               + wcslen(REG_PARAMETERS_KEY_NAME_U) + 1
+               + wcslen(REG_DEVICE_KEY_NAME_U)
+               + GetDigitCount(DeviceIndex);
 
     /* Allocate storage for the string */
+    RegPath = AllocateWideString(PathLength);
+/*
     RegPath = (PWCHAR) HeapAlloc(GetProcessHeap(),
                                  HEAP_ZERO_MEMORY,
                                  PathSize);
+*/
 
     if ( ! RegPath )
     {
@@ -147,11 +151,13 @@
                       KeyHandle) != ERROR_SUCCESS )
     {
         /* Couldn't open the key */
-        HeapFree(GetProcessHeap(), 0, RegPath);
+        FreeMemory(RegPath);
+        /*HeapFree(GetProcessHeap(), 0, RegPath);*/
         return MMSYSERR_ERROR;
     }
 
-    HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, RegPath);
+    FreeMemory(RegPath);
+    /*HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, RegPath);*/
 
     return MMSYSERR_NOERROR;
 }
@@ -206,13 +212,14 @@
             }
 
             /* Account for terminating NULL */
-            ++ MaxNameLength;
-
-            DevicePath = (PWSTR) HeapAlloc(GetProcessHeap(),
-                                           HEAP_ZERO_MEMORY,
-                                           (MaxNameLength +
-                                            strlen("\\\\.\\")) *
-                                            sizeof(WCHAR));
+/*            ++ MaxNameLength;
+
+            DevicePath = (PWSTR) AllocateMemory((MaxNameLength +
+                                                strlen("\\\\.\\")) *
+                                                sizeof(WCHAR));
+*/
+            DevicePath = AllocateWideString(MaxNameLength +
+                                            strlen("\\\\.\\"));
 
             /* Check that the memory allocation was successful */
             if ( ! DevicePath )
@@ -230,8 +237,8 @@
             /* The offset of the string following this prefix */
             ValueName = DevicePath + strlen("\\\\.\\");
 
-            /* Copy this so that it may be overwritten */
-            ValueNameLength = MaxNameLength;
+            /* Copy this so that it may be overwritten - include NULL */
+            ValueNameLength = MaxNameLength + sizeof(WCHAR);
 
             while ( RegEnumValue(DevicesKey,
                                  ValueIndex,
@@ -253,8 +260,9 @@
                 }
 
                 /* Reset variables for the next iteration */
-                ValueNameLength = MaxNameLength;
-                ZeroMemory(ValueName, MaxNameLength);
+                ValueNameLength = MaxNameLength + sizeof(WCHAR);
+                ZeroMemory(ValueName, (MaxNameLength+1)*sizeof(WCHAR));
+                /*ZeroWideString(ValueName);*/
                 ValueDataLength = sizeof(DWORD);
                 ValueData = 0;
                 ValueType = REG_NONE;
@@ -262,7 +270,8 @@
                 ++ ValueIndex;
             }
 
-            HeapFree(GetProcessHeap(), 0, DevicePath);
+            FreeMemory(DevicePath);
+            /*HeapFree(GetProcessHeap(), 0, DevicePath);*/
 
             RegCloseKey(DevicesKey);
         }
@@ -291,7 +300,6 @@
     SOUND_DEVICE_DETECTED_PROC SoundDeviceDetectedProc)
 {
     ULONG DeviceNameLength = 0;
-    ULONG DeviceNameSize = 0;
     PWSTR DeviceName = NULL;
     ULONG Index = 0, Count = 0;
     HANDLE DeviceHandle;
@@ -307,13 +315,12 @@
     DeviceNameLength = wcslen(BaseDeviceName);
     /* Consider the length of the number */
     DeviceNameLength += GetDigitCount(Index);
-    /* ...and the terminating NULL */
-    DeviceNameLength += 1;
-    /* Finally, this is a wide string, so... */
-    DeviceNameSize = DeviceNameLength * sizeof(WCHAR);
-
+
+    DeviceName = AllocateWideString(DeviceNameLength);
+/*
     DeviceName = (PWSTR)
         HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, DeviceNameSize);
+*/
 
     if ( ! DeviceName )
     {
@@ -323,7 +330,8 @@
     while ( DoSearch )
     {
         /* Nothing like a nice clean device name */
-        ZeroMemory(DeviceName, DeviceNameSize);
+        ZeroWideString(DeviceName);
+/*        ZeroMemory(DeviceName, DeviceNameSize);*/
         wsprintf(DeviceName, L"%ls%d", BaseDeviceName, Index);
 
         if ( OpenKernelSoundDeviceByName(DeviceName,
@@ -348,7 +356,8 @@
         }
     }
 
-    HeapFree(GetProcessHeap(), 0, DeviceName);
+    FreeMemory(DeviceName);
+    /*HeapFree(GetProcessHeap(), 0, DeviceName);*/
 
     return MMSYSERR_NOERROR;
 }

Modified: branches/silverblade-audio/lib/drivers/sound/mmebuddy/testing.c
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/sound/mmebuddy/testing.c?rev=34315&r1=34314&r2=34315&view=diff
==============================================================================
--- branches/silverblade-audio/lib/drivers/sound/mmebuddy/testing.c [iso-8859-1] (original)
+++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/testing.c [iso-8859-1] Sat Jul  5 18:23:50 2008
@@ -174,6 +174,18 @@
 }
 
 
+MMRESULT
+TestThreadCallback(
+    IN  struct _SOUND_DEVICE_INSTANCE* Instance,
+    IN  DWORD RequestId,
+    IN  PVOID Data)
+{
+    MessageBox(0, L"Thread Request Callback", L"Woot", MB_OK | MB_TASKMODAL);
+
+    return MMSYSERR_NOERROR;
+}
+
+
 WINAPI VOID
 TestThreading()
 {
@@ -196,16 +208,19 @@
         return;
     }
 
-    Result = StartSoundThread(Instance);
-    if ( Result != MMSYSERR_NOERROR )
-    {
-        MessageBox(0, L"Fail 2", L"Fail 2", MB_OK | MB_TASKMODAL);
-        return;
-    }
+    Result = StartWaveThread(Instance);
+    if ( Result != MMSYSERR_NOERROR )
+    {
+        MessageBox(0, L"Fail 3", L"Fail 3", MB_OK | MB_TASKMODAL);
+        return;
+    }
+
+    MessageBox(0, L"Click to send a request", L"Bai", MB_OK | MB_TASKMODAL);
+    CallSoundThread(Instance, 69, NULL); 
 
     MessageBox(0, L"Click to kill thread", L"Bai", MB_OK | MB_TASKMODAL);
 
-    StopSoundThread(Instance);
+    StopWaveThread(Instance);
 /*
     P
 
@@ -223,7 +238,10 @@
     LPWSTR lpCmdLine,
     int nCmdShow)
 {
+    TestDevEnum();
+/*
     TestThreading();
+*/
     MessageBox(0, L"Le end", L"Bai", MB_OK | MB_TASKMODAL);
     return 0;
 }

Modified: branches/silverblade-audio/lib/drivers/sound/mmebuddy/thread.c
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/sound/mmebuddy/thread.c?rev=34315&r1=34314&r2=34315&view=diff
==============================================================================
--- branches/silverblade-audio/lib/drivers/sound/mmebuddy/thread.c [iso-8859-1] (original)
+++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/thread.c [iso-8859-1] Sat Jul  5 18:23:50 2008
@@ -10,6 +10,7 @@
 
     History:
         4 July 2008 - Created
+        5 July 2008 - Implemented basic request processing
 */
 
 /*
@@ -21,6 +22,7 @@
 #include <mmsystem.h>
 
 #include <mmebuddy.h>
+
 
 DWORD WINAPI
 SoundThreadProc(
@@ -28,20 +30,45 @@
 {
     PSOUND_DEVICE_INSTANCE Instance;
     PSOUND_THREAD Thread;
-    HANDLE Events[2];
+    /*HANDLE Events[2];*/
 
     Instance = (PSOUND_DEVICE_INSTANCE) lpParameter;
     Thread = Instance->Thread;
 
+/*
     Events[0] = Thread->KillEvent;
     Events[1] = Thread->RequestEvent;
+*/
 
     Thread->Running = TRUE;
 
-    MessageBox(0, L"Hi from thread!", L"Hi!", MB_OK | MB_TASKMODAL);
+    /* We're ready to do work */
+    SetEvent(Thread->ReadyEvent);
+
+    /*MessageBox(0, L"Hi from thread!", L"Hi!", MB_OK | MB_TASKMODAL);*/
 
     while ( Thread->Running )
     {
+        /* Wait for some work */
+        WaitForSingleObject(Thread->RequestEvent, INFINITE);
+
+        /* Do the work (request 0 kills the thread) */
+        Thread->Request.Result =
+            Thread->RequestHandler(Instance,
+                                   Thread->Request.RequestId,
+                                   Thread->Request.Data);
+
+        if ( Thread->Request.RequestId == 0 )
+        {
+            Thread->Running = FALSE;
+            Thread->Request.Result = MMSYSERR_NOERROR;
+        }
+
+        /* Notify the caller that the work is done */
+        SetEvent(Thread->ReadyEvent);
+        SetEvent(Thread->DoneEvent);
+
+/*
         DWORD Signalled = 0;
 
         Signalled = WaitForMultipleObjects(2, Events, FALSE, INFINITE);
@@ -52,11 +79,11 @@
         }
         else if ( Signalled == WAIT_OBJECT_0 + 1 )
         {
-            /* ... */
         }
-    }
-
-    MessageBox(0, L"Bye from thread!", L"Bye!", MB_OK | MB_TASKMODAL);
+*/
+    }
+
+    /*MessageBox(0, L"Bye from thread!", L"Bye!", MB_OK | MB_TASKMODAL);*/
 
     ExitThread(0);
     return 0;
@@ -74,21 +101,21 @@
         return MMSYSERR_NOMEM;
     }
 
-    /* Create the request completion event */
-    Thread->RequestCompletionEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
-
-    if ( ! Thread->RequestCompletionEvent )
+    /* Create the 'ready' event */
+    Thread->ReadyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+
+    if ( ! Thread->ReadyEvent )
     {
         CloseHandle(Thread->RequestEvent);
         return MMSYSERR_NOMEM;
     }
 
-    /* Create the kill event */
-    Thread->KillEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
-
-    if ( ! Thread->KillEvent )
-    {
-        CloseHandle(Thread->RequestCompletionEvent);
+    /* Create the 'done' event */
+    Thread->DoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+
+    if ( ! Thread->DoneEvent )
+    {
+        CloseHandle(Thread->ReadyEvent);
         CloseHandle(Thread->RequestEvent);
         return MMSYSERR_NOMEM;
     }
@@ -101,8 +128,13 @@
     IN  PSOUND_THREAD Thread)
 {
     CloseHandle(Thread->RequestEvent);
-    CloseHandle(Thread->RequestCompletionEvent);
-    CloseHandle(Thread->KillEvent);
+    Thread->RequestEvent = INVALID_HANDLE_VALUE;
+
+    CloseHandle(Thread->ReadyEvent);
+    Thread->ReadyEvent = INVALID_HANDLE_VALUE;
+
+    CloseHandle(Thread->DoneEvent);
+    Thread->DoneEvent = INVALID_HANDLE_VALUE;
 
     return MMSYSERR_NOERROR;
 }
@@ -110,12 +142,16 @@
 
 MMRESULT
 StartSoundThread(
-    IN  PSOUND_DEVICE_INSTANCE Instance)
+    IN  PSOUND_DEVICE_INSTANCE Instance,
+    IN  SOUND_THREAD_REQUEST_HANDLER RequestHandler)
 {
     PSOUND_THREAD SoundThread = NULL;
 
     /* Validate parameters */
     if ( ! Instance )
+        return MMSYSERR_INVALPARAM;
+
+    if ( ! RequestHandler )
         return MMSYSERR_INVALPARAM;
 
     /* Only allowed one thread per instance */
@@ -123,9 +159,7 @@
         return MMSYSERR_ERROR;
 
     /* Allocate memory for the thread info */
-    SoundThread = (PSOUND_THREAD) HeapAlloc(GetProcessHeap(),
-                                            HEAP_ZERO_MEMORY,
-                                            sizeof(SOUND_THREAD));
+    SoundThread = AllocateMemoryFor(SOUND_THREAD);
 
     if ( ! SoundThread )
         return MMSYSERR_NOMEM;
@@ -133,19 +167,24 @@
     /* Initialise */
     SoundThread->Running = FALSE;
     SoundThread->Handle = INVALID_HANDLE_VALUE;
-    SoundThread->FirstOperation = NULL;
+    SoundThread->RequestHandler = RequestHandler;
+    SoundThread->ReadyEvent = INVALID_HANDLE_VALUE;
+    SoundThread->RequestEvent = INVALID_HANDLE_VALUE;
+    SoundThread->DoneEvent = INVALID_HANDLE_VALUE;
+
+    /* No need to initialise the requests */
 
     /* Create the events */
     if ( CreateThreadEvents(SoundThread) != MMSYSERR_NOERROR )
     {
-        HeapFree(GetProcessHeap(), 0, SoundThread);
+        FreeMemory(SoundThread);
         return MMSYSERR_NOMEM;
     }
 
     if ( ! SoundThread->RequestEvent )
     {
         CloseHandle(SoundThread->RequestEvent);
-        HeapFree(GetProcessHeap(), 0, SoundThread);
+        FreeMemory(SoundThread);
         return MMSYSERR_NOMEM;
     }
 
@@ -159,7 +198,7 @@
 
     if (SoundThread->Handle == INVALID_HANDLE_VALUE )
     {
-        HeapFree(GetProcessHeap(), 0, SoundThread);
+        FreeMemory(SoundThread);
         return Win32ErrorToMmResult(GetLastError());
     }
 
@@ -182,49 +221,57 @@
     if ( ! Instance->Thread )
         return MMSYSERR_ERROR;
 
-    /* Make the thread quit */
-    Instance->Thread->Running = FALSE;
-
-    /* Wait for the thread to respond to our gentle nudge */
-    SetEvent(Instance->Thread->KillEvent);
-    WaitForSingleObject(Instance->Thread, INFINITE);
-    CloseHandle(Instance->Thread);  /* correct way? */
-
-    /* TODO: A bunch of other stuff - WAIT for thread to die */
-    /* Also clean up the events */
-
+    /* Send request zero to ask the thread to end */
+    CallSoundThread(Instance, 0, NULL);
+
+    /* Wait for the thread to exit */
+    WaitForSingleObject(Instance->Thread->Handle, INFINITE);
+ 
+    /* Finish with the thread */
+    CloseHandle(Instance->Thread->Handle);
+    Instance->Thread->Handle = INVALID_HANDLE_VALUE;
+
+    /* Clean up the thread events */
     DestroyThreadEvents(Instance->Thread);
-    HeapFree(GetProcessHeap(), 0, Instance->Thread);
-
-    return MMSYSERR_NOERROR;
-}
-
-
-/*
-    Thread must be started before calling this!
-*/
-
-MMRESULT
-AddSoundThreadOperation(
-    PSOUND_DEVICE_INSTANCE Instance,
-    DWORD OperationId,
-    SOUND_THREAD_OPERATION OperationFunc)
-{
-    /*SOUND_THREAD_OPERATION OriginalFirstOp;*/
+
+    /* Free memory associated with the thread */
+    FreeMemory(Instance->Thread);
+    Instance->Thread = NULL;
+
+    return MMSYSERR_NOERROR;
+}
+
+MMRESULT
+CallSoundThread(
+    IN  PSOUND_DEVICE_INSTANCE Instance,
+    IN  DWORD RequestId,
+    IN  PVOID RequestData)
+{
+    MMRESULT Result;
 
     if ( ! Instance )
-        return MMSYSERR_INVALPARAM;
-
-    if ( ! OperationFunc )
         return MMSYSERR_INVALPARAM;
 
     if ( ! Instance->Thread )
         return MMSYSERR_ERROR;
 
-/*
-    OriginalFirstOp = Instance->Thread->FirstOperation;
-    Instance->Thread->FirstOperation->Next = 
-*/
-
-    return MMSYSERR_NOTSUPPORTED;
-}
+    /* Wait for the thread to be ready */
+    WaitForSingleObject(Instance->Thread->ReadyEvent, INFINITE);
+
+    /* Load the request */
+    Instance->Thread->Request.DeviceInstance = Instance;
+    Instance->Thread->Request.RequestId = RequestId;
+    Instance->Thread->Request.Data = RequestData;
+    Instance->Thread->Request.Result = MMSYSERR_NOTSUPPORTED;
+
+    /* Notify the thread that there's a request to be processed */
+    SetEvent(Instance->Thread->RequestEvent);
+
+    /* Wait for the thread to be ready (request complete) */
+    WaitForSingleObject(Instance->Thread->DoneEvent, INFINITE);
+
+    /* Grab the result */
+    Result = Instance->Thread->Request.Result;
+
+    return Result;
+}

Modified: branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/wavethread.c
URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/wavethread.c?rev=34315&r1=34314&r2=34315&view=diff
==============================================================================
--- branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/wavethread.c [iso-8859-1] (original)
+++ branches/silverblade-audio/lib/drivers/sound/mmebuddy/wave/wavethread.c [iso-8859-1] Sat Jul  5 18:23:50 2008
@@ -18,21 +18,46 @@
 #include <mmebuddy.h>
 
 MMRESULT
+ProcessWaveThreadRequest(
+    IN  PSOUND_DEVICE_INSTANCE Instance,
+    IN  DWORD RequestId,
+    IN  PVOID Data)
+{
+    /* Just some temporary testing code for now */
+    WCHAR msg[128];
+    wsprintf(msg, L"Request %d received", RequestId);
+
+    MessageBox(0, msg, L"Request", MB_OK | MB_TASKMODAL);
+
+    return MMSYSERR_NOTSUPPORTED;
+}
+
+MMRESULT
 StartWaveThread(
     IN  PSOUND_DEVICE_INSTANCE Instance)
 {
-    MMRESULT Result;
+    MMRESULT Result = MMSYSERR_NOERROR;
 
     if ( ! Instance )
         return MMSYSERR_INVALPARAM;
 
     /* Kick off the thread */
-    Result = StartSoundThread(Instance);
+    Result = StartSoundThread(Instance, ProcessWaveThreadRequest);
     if ( Result != MMSYSERR_NOERROR )
     {
         return Result;
     }
 
     /* AddSoundThreadOperation(Instance, 69, SayHello); */
-    return MMSYSERR_NOTSUPPORTED;
+    return MMSYSERR_NOERROR;
 }
+
+MMRESULT
+StopWaveThread(
+    IN  PSOUND_DEVICE_INSTANCE Instance)
+{
+    if ( ! Instance )
+        return MMSYSERR_INVALPARAM;
+
+    return StopSoundThread(Instance);
+}



More information about the Ros-diffs mailing list