From: <man...@us...> - 2013-10-24 12:09:28
|
Revision: 3002 http://sourceforge.net/p/modplug/code/3002 Author: manxorist Date: 2013-10-24 12:09:20 +0000 (Thu, 24 Oct 2013) Log Message: ----------- [Ref] Replace the convoluted notification forwarding thread with a way simpler solution: If the audio devie is playing, the GUI thread starts a timer which polls the notification buffer. The audio thread simply writes the notifications to the bufffer without notifying the GUI thread at all. This appears to fix sporadic deadlocks in wine which i cannot really explain though. Modified Paths: -------------- trunk/OpenMPT/mptrack/ExceptionHandler.cpp trunk/OpenMPT/mptrack/InputHandler.h trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Mainfrm.h Modified: trunk/OpenMPT/mptrack/ExceptionHandler.cpp =================================================================== --- trunk/OpenMPT/mptrack/ExceptionHandler.cpp 2013-10-24 11:57:14 UTC (rev 3001) +++ trunk/OpenMPT/mptrack/ExceptionHandler.cpp 2013-10-24 12:09:20 UTC (rev 3002) @@ -147,6 +147,11 @@ pMainFrame->gpSoundDevice->Reset(); pMainFrame->gpSoundDevice->Close(); } + if(pMainFrame->m_NotifyTimer) + { + pMainFrame->KillTimer(pMainFrame->m_NotifyTimer); + pMainFrame->m_NotifyTimer = 0; + } } catch(...) { } Modified: trunk/OpenMPT/mptrack/InputHandler.h =================================================================== --- trunk/OpenMPT/mptrack/InputHandler.h 2013-10-24 11:57:14 UTC (rev 3001) +++ trunk/OpenMPT/mptrack/InputHandler.h 2013-10-24 12:09:20 UTC (rev 3002) @@ -16,7 +16,6 @@ enum { WM_MOD_UPDATEPOSITION = (WM_USER+1973), - WM_MOD_NOTIFICATION, WM_MOD_INVALIDATEPATTERNS, WM_MOD_ACTIVATEVIEW, WM_MOD_CHANGEVIEWCLASS, Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2013-10-24 11:57:14 UTC (rev 3001) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2013-10-24 12:09:20 UTC (rev 3002) @@ -89,7 +89,6 @@ ON_UPDATE_COMMAND_UI(ID_INDICATOR_XINFO,OnUpdateXInfo) //rewbs.xinfo ON_UPDATE_COMMAND_UI(ID_INDICATOR_CPU, OnUpdateCPU) ON_UPDATE_COMMAND_UI(IDD_TREEVIEW, OnUpdateControlBarMenu) - ON_MESSAGE(WM_MOD_NOTIFICATION, OnNotification) ON_MESSAGE(WM_MOD_UPDATEPOSITION, OnUpdatePosition) ON_MESSAGE(WM_MOD_INVALIDATEPATTERNS, OnInvalidatePatterns) ON_MESSAGE(WM_MOD_SPECIALKEY, OnSpecialKey) @@ -183,9 +182,7 @@ //---------------------- { - m_hNotifyThread = NULL; - m_dwNotifyThreadId = 0; - m_hNotifyWakeUp = NULL; + m_NotifyTimer = 0; gpSoundDevice = NULL; m_bModTreeHasFocus = false; //rewbs.customKeys @@ -205,8 +202,6 @@ m_szInfoText[0] = 0; m_szXInfoText[0]= 0; //rewbs.xinfo - m_PendingNotificationSempahore = NULL; - MemsetZero(gcolrefVuMeter); // Create Audio Critical Section @@ -261,13 +256,9 @@ #endif // NO_ASIO } - // Create Notify Thread - m_PendingNotificationSempahore = CreateSemaphore(NULL, 0, 1, NULL); - m_hNotifyWakeUp = CreateEvent(NULL, FALSE, FALSE, NULL); - m_hNotifyThread = CreateThread(NULL, 0, NotifyThreadWrapper, NULL, 0, &m_dwNotifyThreadId); // Setup timer OnUpdateUser(NULL); - m_nTimer = SetTimer(1, MPTTIMER_PERIOD, NULL); + m_nTimer = SetTimer(TIMERID_GUI, MPTTIMER_PERIOD, NULL); // Setup Keyboard Hook ghKbdHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, AfxGetInstanceHandle(), GetCurrentThreadId()); @@ -391,23 +382,6 @@ m_nTimer = 0; } if (shMidiIn) midiCloseDevice(); - if(m_hNotifyThread != NULL) - { - PostThreadMessage(m_dwNotifyThreadId, WM_QUIT, 0, 0); - WaitForSingleObject(m_hNotifyThread, INFINITE); - m_dwNotifyThreadId = 0; - m_hNotifyThread = NULL; - } - if(m_hNotifyWakeUp != NULL) - { - CloseHandle(m_hNotifyWakeUp); - m_hNotifyWakeUp = NULL; - } - if(m_PendingNotificationSempahore != NULL) - { - CloseHandle(m_PendingNotificationSempahore); - m_PendingNotificationSempahore = NULL; - } // Delete bitmaps if (bmpPatterns) { @@ -674,57 +648,10 @@ ///////////////////////////////////////////////////////////////////////////// // CMainFrame Sound Library -// Notify thread -DWORD WINAPI CMainFrame::NotifyThreadWrapper(LPVOID) -//-------------------------------------------------- -{ - return ((CMainFrame*)theApp.m_pMainWnd)->NotifyThread(); -} - -DWORD CMainFrame::NotifyThread() +void CMainFrame::OnTimerNotify() //------------------------------ { - MSG msg; - PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); // initialize thread message queue - bool terminate = false; - bool cansend = true; - while(!terminate) - { - HANDLE waitHandles[2]; - waitHandles[0] = m_PendingNotificationSempahore; - waitHandles[1] = m_hNotifyWakeUp; - switch(MsgWaitForMultipleObjects(2, waitHandles, FALSE, 1000, QS_ALLEVENTS)) - { - case WAIT_OBJECT_0 + 0: - // last notification has been handled by gui thread - cansend = true; - break; - case WAIT_OBJECT_0 + 1: - if(cansend) - { - if(PostMessage(WM_MOD_NOTIFICATION, 0, 0)) - { - // message sent, do not send any more until it has been handled - cansend = false; - } - } - break; - case WAIT_OBJECT_0 + 2: - while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - if(msg.message == WM_QUIT) terminate = true; - } - break; - } - } - return 0; -} - - -LRESULT CMainFrame::OnNotification(WPARAM, LPARAM) -//------------------------------------------------ -{ Notification PendingNotification; bool found = false; int64 currenttotalsamples = 0; @@ -763,8 +690,6 @@ { OnUpdatePosition(0, (LPARAM)&PendingNotification); } - ReleaseSemaphore(m_PendingNotificationSempahore, 1, NULL); - return 0; } @@ -901,7 +826,11 @@ } gpSoundDevice->SetMessageReceiver(this); gpSoundDevice->SetSource(this); - return gpSoundDevice->Open(TrackerSettings::Instance().GetSoundDeviceSettings()); + if(!gpSoundDevice->Open(TrackerSettings::Instance().GetSoundDeviceSettings())) + { + return false; + } + return true; } @@ -966,6 +895,11 @@ Util::lock_guard<Util::mutex> lock(m_NotificationBufferMutex); m_NotifyBuffer.clear(); } + if(m_NotifyTimer) + { + KillTimer(m_NotifyTimer); + m_NotifyTimer = 0; + } } @@ -1016,9 +950,6 @@ notifyItem = m_pSndFile->m_pModDoc->GetNotificationItem(); } - // Notify Client - SetEvent(m_hNotifyWakeUp); - // Add an entry to the notification history Notification notification(notifyType, notifyItem, streamPosition, m_pSndFile->m_nRow, m_pSndFile->m_nTickCount, m_pSndFile->m_nCurrentOrder, m_pSndFile->m_nPattern, m_pSndFile->GetMixStat()); @@ -1126,8 +1057,6 @@ m_NotifyBuffer.push(notification); } - SetEvent(m_hNotifyWakeUp); - return true; } @@ -1318,6 +1247,10 @@ Util::lock_guard<Util::mutex> lock(m_SoundDeviceMutex); gpSoundDevice->Start(); } + if(!m_NotifyTimer) + { + m_NotifyTimer = SetTimer(TIMERID_NOTIFY, TrackerSettings::Instance().m_UpdateIntervalMS, NULL); + } return true; } @@ -1330,6 +1263,11 @@ Util::lock_guard<Util::mutex> lock(m_SoundDeviceMutex); gpSoundDevice->Stop(); } + if(m_NotifyTimer) + { + KillTimer(m_NotifyTimer); + m_NotifyTimer = 0; + } audioCloseDevice(); } @@ -1342,6 +1280,11 @@ Util::lock_guard<Util::mutex> lock(m_SoundDeviceMutex); gpSoundDevice->Stop(); } + if(m_NotifyTimer) + { + KillTimer(m_NotifyTimer); + m_NotifyTimer = 0; + } return true; } @@ -2029,9 +1972,24 @@ } -void CMainFrame::OnTimer(UINT_PTR) -//-------------------------------- +void CMainFrame::OnTimer(UINT_PTR timerID) +//---------------------------------------- { + switch(timerID) + { + case TIMERID_GUI: + OnTimerGUI(); + break; + case TIMERID_NOTIFY: + OnTimerNotify(); + break; + } +} + + +void CMainFrame::OnTimerGUI() +//--------------------------- +{ // Display Time in status bar CSoundFile::samplecount_t time = 0; if(m_pSndFile != nullptr && m_pSndFile->GetSampleRate() != 0) Modified: trunk/OpenMPT/mptrack/Mainfrm.h =================================================================== --- trunk/OpenMPT/mptrack/Mainfrm.h 2013-10-24 11:57:14 UTC (rev 3001) +++ trunk/OpenMPT/mptrack/Mainfrm.h 2013-10-24 12:09:20 UTC (rev 3002) @@ -241,6 +241,8 @@ #define MAX_UPDATE_HISTORY 256 // same as SNDDEV_MAXBUFFERS #include "Notification.h" +#define TIMERID_GUI 1 +#define TIMERID_NOTIFY 2 #include "mainbar.h" #include "TrackerSettings.h" @@ -273,10 +275,9 @@ // Low-Level Audio mutable Util::mutex m_SoundDeviceMutex; ISoundDevice *gpSoundDevice; + UINT_PTR m_NotifyTimer; Dither m_Dither; - HANDLE m_hNotifyWakeUp; - HANDLE m_hNotifyThread; - DWORD m_dwNotifyThreadId; + static LONG gnLVuMeter, gnRVuMeter; static bool gnClipLeft, gnClipRight; @@ -303,7 +304,6 @@ // Notification Buffer Util::mutex m_NotificationBufferMutex; // to avoid deadlocks, this mutex should only be taken as a innermost lock, i.e. do not block on anything while holding this mutex Util::fixed_size_queue<Notification,MAX_UPDATE_HISTORY> m_NotifyBuffer; - HANDLE m_PendingNotificationSempahore; // protects the one notification that is in flight from the notification thread to the gui thread from being freed while the gui thread still uses it // Instrument preview in tree view CSoundFile m_WaveFile; @@ -320,8 +320,6 @@ static void UpdateDspEffects(CSoundFile &sndFile, bool reset=false); static void UpdateAudioParameters(CSoundFile &sndFile, bool reset=false); static void CalcStereoVuMeters(int *, unsigned long, unsigned long); - static DWORD WINAPI NotifyThreadWrapper(LPVOID); - DWORD NotifyThread(); // from ISoundSource void FillAudioBufferLocked(IFillAudioBuffer &callback); @@ -476,6 +474,9 @@ virtual void Dump(CDumpContext& dc) const; #endif + void OnTimerGUI(); + void OnTimerNotify(); + // Message map functions //{{AFX_MSG(CMainFrame) public: @@ -513,7 +514,6 @@ afx_msg void OnPanic(); afx_msg void OnReportBug(); //rewbs.customKeys afx_msg BOOL OnInternetLink(UINT nID); - afx_msg LRESULT OnNotification(WPARAM, LPARAM lParam); afx_msg LRESULT OnUpdatePosition(WPARAM, LPARAM lParam); afx_msg void OnExampleSong(UINT nId); afx_msg void OnOpenTemplateModule(UINT nId); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |