From 1a5817f6fdcf2fd5967809422c252e503d930b13 Mon Sep 17 00:00:00 2001 From: Shawn Hoffman Date: Sat, 9 Jan 2010 19:06:23 +0000 Subject: [PATCH] from BhaaL: linux compile fix for r4794, Event::Wait now supports a timeout (default to INFINITE), and it returns true when the timeout expired. fixes issue 1974 git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4799 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Src/Thread.cpp | 35 ++++++++++++--- Source/Core/Common/Src/Thread.h | 7 ++- .../Plugin_Wiimote/Src/ConfigRecordingDlg.cpp | 2 +- .../Plugin_Wiimote/Src/wiimote_real.cpp | 45 +++++++++---------- .../Plugins/Plugin_Wiimote/Src/wiimote_real.h | 8 +++- 5 files changed, 64 insertions(+), 33 deletions(-) diff --git a/Source/Core/Common/Src/Thread.cpp b/Source/Core/Common/Src/Thread.cpp index 05a930b9f3..bb0d591771 100644 --- a/Source/Core/Common/Src/Thread.cpp +++ b/Source/Core/Common/Src/Thread.cpp @@ -139,9 +139,9 @@ void Event::Set() SetEvent(m_hEvent); } -void Event::Wait() +bool Event::Wait(const u32 timeout) { - WaitForSingleObject(m_hEvent, INFINITE); + return WaitForSingleObject(m_hEvent, timeout) != WAIT_OBJECT_0; } inline HRESULT MsgWaitForSingleObject(HANDLE handle, DWORD timeout) @@ -400,17 +400,42 @@ void Event::Set() } -void Event::Wait() +bool Event::Wait(const u32 timeout) { + bool timedout = false; + struct timespec wait; pthread_mutex_lock(&mutex_); - while (!is_set_) + if (timeout != INFINITE) { - pthread_cond_wait(&event_, &mutex_); + struct timeval now; + gettimeofday(&now, NULL); + + memset(&wait, 0, sizeof(wait)); + //TODO: timespec also has nanoseconds, but do we need them? + //as consequence, waiting is limited to seconds for now. + //the following just looks ridiculous, and probably fails for + //values 429 < ms <= 999 since it overflows the long. + //wait.tv_nsec = (now.tv_usec + (timeout % 1000) * 1000) * 1000); + wait.tv_sec = now.tv_sec + (timeout / 1000); + } + + while (!is_set_ && !timedout) + { + if (timeout == INFINITE) + { + pthread_cond_wait(&event_, &mutex_); + } + else + { + timedout = pthread_cond_timedwait(&event_, &mutex_, &wait) == ETIMEDOUT; + } } is_set_ = false; pthread_mutex_unlock(&mutex_); + + return timedout; } #endif diff --git a/Source/Core/Common/Src/Thread.h b/Source/Core/Common/Src/Thread.h index ec1c3884bc..4df20da844 100644 --- a/Source/Core/Common/Src/Thread.h +++ b/Source/Core/Common/Src/Thread.h @@ -59,6 +59,10 @@ #ifndef INFINITE #define INFINITE 0xffffffff #endif + +//for gettimeofday and struct time(val|spec) +#include +#include #endif @@ -144,7 +148,8 @@ public: void Shutdown(); void Set(); - void Wait(); + //returns whether the wait timed out + bool Wait(const u32 timeout = INFINITE); #ifdef _WIN32 void MsgWait(); #else diff --git a/Source/Plugins/Plugin_Wiimote/Src/ConfigRecordingDlg.cpp b/Source/Plugins/Plugin_Wiimote/Src/ConfigRecordingDlg.cpp index 538e3f0c3d..1c64f3c80d 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/ConfigRecordingDlg.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/ConfigRecordingDlg.cpp @@ -98,7 +98,7 @@ void WiimoteRecordingConfigDialog::CloseClick(wxCommandEvent& event) { case ID_CLOSE: if (g_RealWiiMoteInitialized) - SetEvent(WiiMoteReal::g_StopThreadTemporary); //WiiMoteReal::SafecloseRemoteFunc over takes the closing of the Dlg + WiiMoteReal::g_StopThreadTemporary.Set(); //WiiMoteReal::SafecloseRemoteFunc over takes the closing of the Dlg else Close(); break; diff --git a/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.cpp b/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.cpp index 36d3b9e3c3..bfa88f60c4 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.cpp +++ b/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.cpp @@ -61,8 +61,8 @@ Common::Thread* g_pReadThread = NULL; int g_NumberOfWiiMotes; CWiiMote* g_WiiMotes[MAX_WIIMOTES]; bool g_Shutdown = false; -HANDLE g_StartThread = false; -HANDLE g_StopThreadTemporary; +Common::Event g_StartThread; +Common::Event g_StopThreadTemporary; bool g_LocalThread = true; bool g_IRSensing = false; bool g_MotionSensing = false; @@ -530,8 +530,8 @@ void Update(int _WiimoteNumber) time to avoid a potential collision. */ THREAD_RETURN ReadWiimote_ThreadFunc(void* arg) { - WiiMoteReal::g_StopThreadTemporary = CreateEvent(NULL, TRUE, FALSE, NULL); - WiiMoteReal::g_StartThread = CreateEvent(NULL, TRUE, FALSE, NULL); + g_StopThreadTemporary.Init(); + g_StartThread.Init(); while (!g_Shutdown) { @@ -545,37 +545,34 @@ THREAD_RETURN ReadWiimote_ThreadFunc(void* arg) } else { - switch (WaitForSingleObject(WiiMoteReal::g_StopThreadTemporary,0)) + if (!g_StopThreadTemporary.Wait(0)) { - // Event object was signaled, exiting thread to close ConfigRecordingDlg - case WAIT_OBJECT_0: - + // Event object was signaled, exiting thread to close ConfigRecordingDlg new Common::Thread(SafeCloseReadWiimote_ThreadFunc, NULL); - SetEvent(WiiMoteReal::g_StartThread); //tell the new thread to get going + g_StartThread.Set(); //tell the new thread to get going return 0; - - default: - ReadWiimote(); } - - + else + ReadWiimote(); } } return 0; } -THREAD_RETURN SafeCloseReadWiimote_ThreadFunc(void* arg) // Thread to avoid racing conditions by directly closing of ReadWiimote_ThreadFunc() resp. ReadWiimote() // shutting down the Dlg while still beeing @ReadWiimote will result in a crash; +// Thread to avoid racing conditions by directly closing of ReadWiimote_ThreadFunc() resp. ReadWiimote() +// shutting down the Dlg while still beeing @ReadWiimote will result in a crash; +THREAD_RETURN SafeCloseReadWiimote_ThreadFunc(void* arg) { - WiiMoteReal::g_Shutdown = true; - WaitForSingleObject(WiiMoteReal::g_StartThread,INFINITE); //Ready to start cleaning + g_Shutdown = true; + g_StartThread.Wait(); //Ready to start cleaning - if (g_RealWiiMoteInitialized) - WiiMoteReal::Shutdown(); - m_RecordingConfigFrame->Close(true); - if (!g_RealWiiMoteInitialized) - WiiMoteReal::Initialize(); - - return 0; + if (g_RealWiiMoteInitialized) + Shutdown(); + m_RecordingConfigFrame->Close(true); + if (!g_RealWiiMoteInitialized) + Initialize(); + + return 0; } // WiiMote Pair-Up #ifdef WIN32 diff --git a/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.h b/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.h index 72dda054b3..92efe5ed56 100644 --- a/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.h +++ b/Source/Plugins/Plugin_Wiimote/Src/wiimote_real.h @@ -23,6 +23,10 @@ #include "wiiuse.h" #include "ChunkFile.h" +#ifndef EXCLUDE_H +//this one is required for Common::Event +#include "Thread.h" +#endif namespace WiiMoteReal { @@ -48,8 +52,8 @@ bool IRDataOK(struct wiimote_t* wm); #ifndef EXCLUDE_H extern wiimote_t** g_WiiMotesFromWiiUse; extern bool g_Shutdown; - extern HANDLE g_StopThreadTemporary; - extern HANDLE g_StartThread; + extern Common::Event g_StartThread; + extern Common::Event g_StopThreadTemporary; extern int g_NumberOfWiiMotes; extern bool g_MotionSensing; extern bool g_IRSensing;