From 02fc68ea5d1466998c7d59b2882a5f9e348de24b Mon Sep 17 00:00:00 2001 From: comex Date: Wed, 4 Sep 2013 03:21:38 -0400 Subject: [PATCH] While we're at it, explicitly wake up the Wiimote thread rather than using a 1s timeout. This only matters if reads are not constantly being completed by reports anyway, but seems like a good idea. --- .../Core/Core/Src/HW/WiimoteReal/IODummy.cpp | 3 +++ Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp | 25 ++++++++++++++++--- Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp | 20 ++++++++++++--- .../Core/Core/Src/HW/WiimoteReal/IOdarwin.mm | 5 ++++ .../Core/Src/HW/WiimoteReal/WiimoteReal.cpp | 14 ++++++++++- .../Core/Src/HW/WiimoteReal/WiimoteReal.h | 2 ++ 6 files changed, 60 insertions(+), 9 deletions(-) diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp index 870d281326..e1ca6d603c 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IODummy.cpp @@ -58,6 +58,9 @@ bool Wiimote::IsConnected() const return false; } +void Wiimote::IOWakeup() +{} + int Wiimote::IORead(u8* buf) { return 0; diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp index 014eadc9a8..826b9e67ce 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IONix.cpp @@ -181,26 +181,43 @@ bool Wiimote::IsConnected() const return cmd_sock != -1;// && int_sock != -1; } +void Wiimote::IOWakeup() +{ + char c = 0; + if (write(wakeup_pipe_w, &c, 1) != 1) + { + ERROR_LOG(WIIMOTE, "Unable to write to wakeup pipe."); + } +} + // positive = read packet // negative = didn't read packet // zero = error int Wiimote::IORead(u8* buf) { // Block select for 1/2000th of a second - timeval tv; - tv.tv_sec = 0; - tv.tv_usec = WIIMOTE_DEFAULT_TIMEOUT * 1000; fd_set fds; FD_ZERO(&fds); FD_SET(int_sock, &fds); + FD_SET(wakeup_pipe_r, &fds); - if (select(int_sock + 1, &fds, NULL, NULL, &tv) == -1) + if (select(int_sock + 1, &fds, NULL, NULL, NULL) == -1) { ERROR_LOG(WIIMOTE, "Unable to select wiimote %i input socket.", index + 1); return -1; } + if (FD_ISSET(wakeup_pipe_r, &fds)) + { + char c; + if (read(wakeup_pipe_r, &c, 1) != 1) + { + ERROR_LOG(WIIMOTE, "Unable to read from wakeup pipe."); + } + return -1; + } + if (!FD_ISSET(int_sock, &fds)) return -1; diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp index 866284b323..206c11ab64 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOWin.cpp @@ -142,6 +142,7 @@ namespace WiimoteReal int _IOWrite(HANDLE &dev_handle, OVERLAPPED &hid_overlap_write, enum win_bt_stack_t &stack, const u8* buf, int len); int _IORead(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read, u8* buf, int index); +void _IOWakeup(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read); template void ProcessWiimotes(bool new_scan, T& callback); @@ -557,6 +558,11 @@ bool Wiimote::IsConnected() const return dev_handle != 0; } +void _IOWakeup(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read) +{ + CancelIoEx(dev_handle, &hid_overlap_read); +} + // positive = read packet // negative = didn't read packet // zero = error @@ -575,7 +581,7 @@ int _IORead(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read, u8* buf, int index if (ERROR_IO_PENDING == read_err) { - auto const wait_result = WaitForSingleObject(hid_overlap_read.hEvent, WIIMOTE_DEFAULT_TIMEOUT); + auto const wait_result = WaitForSingleObject(hid_overlap_read.hEvent, INFINITE); if (WAIT_TIMEOUT == wait_result) { CancelIo(dev_handle); @@ -592,10 +598,10 @@ int _IORead(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read, u8* buf, int index if (ERROR_OPERATION_ABORTED == overlapped_err) { + /* if (buf[1] != 0) - WARN_LOG(WIIMOTE, "Packet ignored. This may indicate a problem (timeout is %i ms).", - WIIMOTE_DEFAULT_TIMEOUT); - + WARN_LOG(WIIMOTE, "Packet ignored. This may indicate a problem."); + */ return -1; } @@ -615,6 +621,12 @@ int _IORead(HANDLE &dev_handle, OVERLAPPED &hid_overlap_read, u8* buf, int index return bytes + 1; } +void Wiimote::IOWakeup() +{ + _IOWakeup(dev_handle, hid_overlap_read); +} + + // positive = read packet // negative = didn't read packet // zero = error diff --git a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm index 17e867bc7a..c560ceb652 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm +++ b/Source/Core/Core/Src/HW/WiimoteReal/IOdarwin.mm @@ -247,6 +247,11 @@ bool Wiimote::IsConnected() const return m_connected; } +void Wiimote::IOWakeup() +{ + CFRunLoopStop(m_wiimote_thread_run_loop); +} + int Wiimote::IORead(unsigned char *buf) { input = buf; diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp index aead9d60fa..ddf54dfc5a 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.cpp @@ -52,6 +52,14 @@ Wiimote::Wiimote() , m_need_prepare() { #if defined(__linux__) && HAVE_BLUEZ + int fds[2]; + if (pipe(fds)) + { + ERROR_LOG(WIIMOTE, "pipe failed"); + abort(); + } + wakeup_pipe_w = fds[1]; + wakeup_pipe_r = fds[0]; bdaddr = (bdaddr_t){{0, 0, 0, 0, 0, 0}}; #endif } @@ -59,9 +67,12 @@ Wiimote::Wiimote() Wiimote::~Wiimote() { StopThread(); - ClearReadQueue(); m_write_reports.Clear(); +#if defined(__linux__) && HAVE_BLUEZ + close(wakeup_pipe_w); + close(wakeup_pipe_r); +#endif } // to be called from CPU thread @@ -82,6 +93,7 @@ void Wiimote::WriteReport(Report rpt) } m_write_reports.Push(std::move(rpt)); + IOWakeup(); } // to be called from CPU thread diff --git a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h index e48567acbb..314fb2e83c 100644 --- a/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h +++ b/Source/Core/Core/Src/HW/WiimoteReal/WiimoteReal.h @@ -84,6 +84,7 @@ public: bdaddr_t bdaddr; // Bluetooth address int cmd_sock; // Command socket int int_sock; // Interrupt socket + int wakeup_pipe_w, wakeup_pipe_r; #elif defined(_WIN32) std::basic_string devicepath; // Unique wiimote reference @@ -103,6 +104,7 @@ private: int IORead(u8* buf); int IOWrite(u8 const* buf, int len); + void IOWakeup(); void ThreadFunc(); void SetReady();