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.
This commit is contained in:
comex 2013-09-04 03:21:38 -04:00
parent 906de748bd
commit 02fc68ea5d
6 changed files with 60 additions and 9 deletions

View File

@ -58,6 +58,9 @@ bool Wiimote::IsConnected() const
return false;
}
void Wiimote::IOWakeup()
{}
int Wiimote::IORead(u8* buf)
{
return 0;

View File

@ -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;

View File

@ -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 <typename T>
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

View File

@ -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;

View File

@ -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

View File

@ -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<TCHAR> 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();