1
0
Fork 0

Codechange: Use std::mutex instead of CRITICAL_SECTION in win32_m

pull/7653/head
Niels Martin Hansen 2019-07-01 17:52:28 +02:00
parent 2e23c5ec15
commit c74df8581d
1 changed files with 18 additions and 33 deletions

View File

@ -19,6 +19,7 @@
#include "midifile.hpp" #include "midifile.hpp"
#include "midi.h" #include "midi.h"
#include "../base_media_base.h" #include "../base_media_base.h"
#include <mutex>
#include "../safeguards.h" #include "../safeguards.h"
@ -32,7 +33,7 @@ static struct {
UINT time_period; ///< obtained timer precision value UINT time_period; ///< obtained timer precision value
HMIDIOUT midi_out; ///< handle to open midiOut HMIDIOUT midi_out; ///< handle to open midiOut
UINT timer_id; ///< ID of active multimedia timer UINT timer_id; ///< ID of active multimedia timer
CRITICAL_SECTION lock; ///< synchronization for playback status fields std::mutex lock; ///< synchronization for playback status fields
bool playing; ///< flag indicating that playback is active bool playing; ///< flag indicating that playback is active
bool do_start; ///< flag for starting playback of next_file at next opportunity bool do_start; ///< flag for starting playback of next_file at next opportunity
@ -108,17 +109,17 @@ static void TransmitSysexConst(byte *msg_start, size_t length)
*/ */
void CALLBACK TimerCallback(UINT uTimerID, UINT, DWORD_PTR dwUser, DWORD_PTR, DWORD_PTR) void CALLBACK TimerCallback(UINT uTimerID, UINT, DWORD_PTR dwUser, DWORD_PTR, DWORD_PTR)
{ {
/* Try to check playback status changes. /* Ensure only one timer callback is running at once, and prevent races on status flags */
* If _midi is already locked, skip checking for this cycle and try again std::unique_lock<std::mutex> mutex_lock(_midi.lock, std::defer_lock);
* next cycle, instead of waiting for locks in the realtime callback. */ if (!mutex_lock.try_lock()) return;
if (TryEnterCriticalSection(&_midi.lock)) {
{
/* check for stop */ /* check for stop */
if (_midi.do_stop) { if (_midi.do_stop) {
DEBUG(driver, 2, "Win32-MIDI: timer: do_stop is set"); DEBUG(driver, 2, "Win32-MIDI: timer: do_stop is set");
midiOutReset(_midi.midi_out); midiOutReset(_midi.midi_out);
_midi.playing = false; _midi.playing = false;
_midi.do_stop = false; _midi.do_stop = false;
LeaveCriticalSection(&_midi.lock);
return; return;
} }
@ -155,7 +156,6 @@ void CALLBACK TimerCallback(UINT uTimerID, UINT, DWORD_PTR dwUser, DWORD_PTR, DW
DEBUG(driver, 2, "Win32-MIDI: timer: not playing, stopping timer"); DEBUG(driver, 2, "Win32-MIDI: timer: not playing, stopping timer");
timeKillEvent(uTimerID); timeKillEvent(uTimerID);
_midi.timer_id = 0; _midi.timer_id = 0;
LeaveCriticalSection(&_midi.lock);
return; return;
} }
@ -170,13 +170,10 @@ void CALLBACK TimerCallback(UINT uTimerID, UINT, DWORD_PTR dwUser, DWORD_PTR, DW
int vol = ScaleVolume(_midi.channel_volumes[ch], _midi.current_volume); int vol = ScaleVolume(_midi.channel_volumes[ch], _midi.current_volume);
TransmitChannelMsg(MIDIST_CONTROLLER | ch, MIDICT_CHANVOLUME, vol); TransmitChannelMsg(MIDIST_CONTROLLER | ch, MIDICT_CHANVOLUME, vol);
} }
} } else {
else {
volume_throttle--; volume_throttle--;
} }
} }
LeaveCriticalSection(&_midi.lock);
} }
/* skip beginning of file? */ /* skip beginning of file? */
@ -313,12 +310,9 @@ void CALLBACK TimerCallback(UINT uTimerID, UINT, DWORD_PTR dwUser, DWORD_PTR, DW
void MusicDriver_Win32::PlaySong(const MusicSongInfo &song) void MusicDriver_Win32::PlaySong(const MusicSongInfo &song)
{ {
DEBUG(driver, 2, "Win32-MIDI: PlaySong: entry"); DEBUG(driver, 2, "Win32-MIDI: PlaySong: entry");
EnterCriticalSection(&_midi.lock); std::lock_guard mutex_lock(_midi.lock);
if (!_midi.next_file.LoadSong(song)) { if (!_midi.next_file.LoadSong(song)) return;
LeaveCriticalSection(&_midi.lock);
return;
}
_midi.next_segment.start = song.override_start; _midi.next_segment.start = song.override_start;
_midi.next_segment.end = song.override_end; _midi.next_segment.end = song.override_end;
@ -332,17 +326,14 @@ void MusicDriver_Win32::PlaySong(const MusicSongInfo &song)
DEBUG(driver, 2, "Win32-MIDI: PlaySong: starting timer"); DEBUG(driver, 2, "Win32-MIDI: PlaySong: starting timer");
_midi.timer_id = timeSetEvent(_midi.time_period, _midi.time_period, TimerCallback, (DWORD_PTR)this, TIME_PERIODIC | TIME_CALLBACK_FUNCTION); _midi.timer_id = timeSetEvent(_midi.time_period, _midi.time_period, TimerCallback, (DWORD_PTR)this, TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
} }
LeaveCriticalSection(&_midi.lock);
} }
void MusicDriver_Win32::StopSong() void MusicDriver_Win32::StopSong()
{ {
DEBUG(driver, 2, "Win32-MIDI: StopSong: entry"); DEBUG(driver, 2, "Win32-MIDI: StopSong: entry");
EnterCriticalSection(&_midi.lock); std::lock_guard mutex_lock(_midi.lock);
DEBUG(driver, 2, "Win32-MIDI: StopSong: setting flag"); DEBUG(driver, 2, "Win32-MIDI: StopSong: setting flag");
_midi.do_stop = true; _midi.do_stop = true;
LeaveCriticalSection(&_midi.lock);
} }
bool MusicDriver_Win32::IsSongPlaying() bool MusicDriver_Win32::IsSongPlaying()
@ -352,17 +343,14 @@ bool MusicDriver_Win32::IsSongPlaying()
void MusicDriver_Win32::SetVolume(byte vol) void MusicDriver_Win32::SetVolume(byte vol)
{ {
EnterCriticalSection(&_midi.lock); std::lock_guard mutex_lock(_midi.lock);
_midi.new_volume = vol; _midi.new_volume = vol;
LeaveCriticalSection(&_midi.lock);
} }
const char *MusicDriver_Win32::Start(const char * const *parm) const char *MusicDriver_Win32::Start(const char * const *parm)
{ {
DEBUG(driver, 2, "Win32-MIDI: Start: initializing"); DEBUG(driver, 2, "Win32-MIDI: Start: initializing");
InitializeCriticalSection(&_midi.lock);
int resolution = GetDriverParamInt(parm, "resolution", 5); int resolution = GetDriverParamInt(parm, "resolution", 5);
int port = GetDriverParamInt(parm, "port", -1); int port = GetDriverParamInt(parm, "port", -1);
@ -405,7 +393,7 @@ const char *MusicDriver_Win32::Start(const char * const *parm)
void MusicDriver_Win32::Stop() void MusicDriver_Win32::Stop()
{ {
EnterCriticalSection(&_midi.lock); std::lock_guard mutex_lock(_midi.lock);
if (_midi.timer_id) { if (_midi.timer_id) {
timeKillEvent(_midi.timer_id); timeKillEvent(_midi.timer_id);
@ -415,7 +403,4 @@ void MusicDriver_Win32::Stop()
timeEndPeriod(_midi.time_period); timeEndPeriod(_midi.time_period);
midiOutReset(_midi.midi_out); midiOutReset(_midi.midi_out);
midiOutClose(_midi.midi_out); midiOutClose(_midi.midi_out);
LeaveCriticalSection(&_midi.lock);
DeleteCriticalSection(&_midi.lock);
} }