https://git.reactos.org/?p=reactos.git;a=commitdiff;h=eab8a0b968cbb7ef08933…
commit eab8a0b968cbb7ef0893326a5e87704c4da45c7f
Author: Thomas Faber <thomas.faber(a)reactos.org>
AuthorDate: Tue Feb 27 18:36:22 2018 +0100
Commit: Thomas Faber <thomas.faber(a)reactos.org>
CommitDate: Thu Mar 1 08:58:33 2018 +0100
[BEEPMIDI] Don't busy-wait when no notes are playing. CORE-12860
- Use a new work_available event to allow ProcessPlayingNotes to sleep when no
notes are to be played.
- Get rid of the pointless thread_termination_complete event, wait on the
thread handle instead.
- Don't leak thread_handle.
---
dll/win32/beepmidi/beepmidi.c | 30 ++++++++++++++++++------------
1 file changed, 18 insertions(+), 12 deletions(-)
diff --git a/dll/win32/beepmidi/beepmidi.c b/dll/win32/beepmidi/beepmidi.c
index 5fdf62d7bc..b23999845f 100644
--- a/dll/win32/beepmidi/beepmidi.c
+++ b/dll/win32/beepmidi/beepmidi.c
@@ -95,7 +95,7 @@ typedef struct _DeviceInfo
HANDLE thread_handle;
BOOL terminate_thread;
- HANDLE thread_termination_complete;
+ HANDLE work_available;
} DeviceInfo;
DeviceInfo* the_device;
@@ -127,7 +127,7 @@ ProcessPlayingNotes(
/* We lock the note list only while accessing it */
#ifdef CONTINUOUS_NOTES
- while ( ! device_info->terminate_thread )
+ while ( WaitForSingleObject(the_device->work_available, INFINITE),
!device_info->terminate_thread )
#endif
{
NoteNode* node;
@@ -198,10 +198,6 @@ ProcessPlayingNotes(
LeaveCriticalSection(&device_lock);
}
-#ifdef CONTINUOUS_NOTES
- SetEvent(device_info->thread_termination_complete);
-#endif
-
return 0;
}
@@ -346,9 +342,9 @@ OpenDevice(
/* This is threading-related code */
#ifdef CONTINUOUS_NOTES
- the_device->thread_termination_complete = CreateEvent(NULL, FALSE, FALSE, NULL);
+ the_device->work_available = CreateEvent(NULL, TRUE, FALSE, NULL);
- if ( ! the_device->thread_termination_complete )
+ if ( ! the_device->work_available )
{
DPRINT("CreateEvent failed\n");
HeapFree(heap, 0, the_device);
@@ -365,7 +361,7 @@ OpenDevice(
if ( ! the_device->thread_handle )
{
DPRINT("CreateThread failed\n");
- CloseHandle(the_device->thread_termination_complete);
+ CloseHandle(the_device->work_available);
HeapFree(heap, 0, the_device);
return MMSYSERR_NOMEM;
}
@@ -391,10 +387,11 @@ CloseDevice(DeviceInfo* device_info)
/* If we're working in threaded mode we need to wait for thread to die */
#ifdef CONTINUOUS_NOTES
the_device->terminate_thread = TRUE;
+ SetEvent(device_info->work_available);
- WaitForSingleObject(the_device->thread_termination_complete, INFINITE);
-
- CloseHandle(the_device->thread_termination_complete);
+ WaitForSingleObject(the_device->thread_handle, INFINITE);
+ CloseHandle(the_device->thread_handle);
+ CloseHandle(the_device->work_available);
#endif
/* Let the client application know the device is closing */
@@ -451,6 +448,11 @@ StopNote(
DPRINT("Note stopped - now playing %d notes\n", (int)
device_info->playing_notes_count);
+#ifdef CONTINUOUS_NOTES
+ if (device_info->playing_notes_count == 0)
+ ResetEvent(device_info->work_available);
+#endif
+
LeaveCriticalSection(&device_lock);
device_info->refresh_notes = TRUE;
@@ -561,6 +563,10 @@ PlayNote(
}
*/
+#ifdef CONTINUOUS_NOTES
+ SetEvent(device_info->work_available);
+#endif
+
LeaveCriticalSection(&device_lock);
DPRINT("Note started - now playing %d notes\n", (int)
device_info->playing_notes_count);