[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.
This commit is contained in:
Thomas Faber 2018-02-27 18:36:22 +01:00
parent 2f11904000
commit eab8a0b968
No known key found for this signature in database
GPG key ID: 076E7C3D44720826

View file

@ -95,7 +95,7 @@ typedef struct _DeviceInfo
HANDLE thread_handle; HANDLE thread_handle;
BOOL terminate_thread; BOOL terminate_thread;
HANDLE thread_termination_complete; HANDLE work_available;
} DeviceInfo; } DeviceInfo;
DeviceInfo* the_device; DeviceInfo* the_device;
@ -127,7 +127,7 @@ ProcessPlayingNotes(
/* We lock the note list only while accessing it */ /* We lock the note list only while accessing it */
#ifdef CONTINUOUS_NOTES #ifdef CONTINUOUS_NOTES
while ( ! device_info->terminate_thread ) while ( WaitForSingleObject(the_device->work_available, INFINITE), !device_info->terminate_thread )
#endif #endif
{ {
NoteNode* node; NoteNode* node;
@ -198,10 +198,6 @@ ProcessPlayingNotes(
LeaveCriticalSection(&device_lock); LeaveCriticalSection(&device_lock);
} }
#ifdef CONTINUOUS_NOTES
SetEvent(device_info->thread_termination_complete);
#endif
return 0; return 0;
} }
@ -346,9 +342,9 @@ OpenDevice(
/* This is threading-related code */ /* This is threading-related code */
#ifdef CONTINUOUS_NOTES #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"); DPRINT("CreateEvent failed\n");
HeapFree(heap, 0, the_device); HeapFree(heap, 0, the_device);
@ -365,7 +361,7 @@ OpenDevice(
if ( ! the_device->thread_handle ) if ( ! the_device->thread_handle )
{ {
DPRINT("CreateThread failed\n"); DPRINT("CreateThread failed\n");
CloseHandle(the_device->thread_termination_complete); CloseHandle(the_device->work_available);
HeapFree(heap, 0, the_device); HeapFree(heap, 0, the_device);
return MMSYSERR_NOMEM; 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 */ /* If we're working in threaded mode we need to wait for thread to die */
#ifdef CONTINUOUS_NOTES #ifdef CONTINUOUS_NOTES
the_device->terminate_thread = TRUE; the_device->terminate_thread = TRUE;
SetEvent(device_info->work_available);
WaitForSingleObject(the_device->thread_termination_complete, INFINITE); WaitForSingleObject(the_device->thread_handle, INFINITE);
CloseHandle(the_device->thread_handle);
CloseHandle(the_device->thread_termination_complete); CloseHandle(the_device->work_available);
#endif #endif
/* Let the client application know the device is closing */ /* 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); 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); LeaveCriticalSection(&device_lock);
device_info->refresh_notes = TRUE; device_info->refresh_notes = TRUE;
@ -561,6 +563,10 @@ PlayNote(
} }
*/ */
#ifdef CONTINUOUS_NOTES
SetEvent(device_info->work_available);
#endif
LeaveCriticalSection(&device_lock); LeaveCriticalSection(&device_lock);
DPRINT("Note started - now playing %d notes\n", (int) device_info->playing_notes_count); DPRINT("Note started - now playing %d notes\n", (int) device_info->playing_notes_count);