From c4b7f42494d40768739b856e83d5e729646d8805 Mon Sep 17 00:00:00 2001
From: Ingo Ruhnke <grumbel@gmx.de>
Date: Wed, 29 Jul 2009 15:52:27 +0200
Subject: [PATCH] Fixed some bugs in threading, use threading for the wired
 controller too

---
 src/usb_read_thread.cpp             |  2 +-
 src/xbox360_controller.cpp          | 17 ++++++++++++++++-
 src/xbox360_controller.hpp          |  3 +++
 src/xbox360_wireless_controller.cpp |  2 ++
 4 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/src/usb_read_thread.cpp b/src/usb_read_thread.cpp
index 9be1d32..9008973 100644
--- a/src/usb_read_thread.cpp
+++ b/src/usb_read_thread.cpp
@@ -79,7 +79,7 @@ USBReadThread::run()
     {
       uint8_t* data = new uint8_t[m_read_length];
 
-      int ret = usb_interrupt_read(m_handle, m_read_endpoint, (char*)data, sizeof(data), 0 /*timeout*/);
+      int ret = usb_interrupt_read(m_handle, m_read_endpoint, (char*)data, m_read_length, 0 /*timeout*/);
 
       {
         boost::mutex::scoped_lock lock(m_read_buffer_mutex);
diff --git a/src/xbox360_controller.cpp b/src/xbox360_controller.cpp
index 31b7728..b19a7f0 100644
--- a/src/xbox360_controller.cpp
+++ b/src/xbox360_controller.cpp
@@ -22,6 +22,8 @@
 #include <sstream>
 #include <iostream>
 #include <boost/format.hpp>
+
+#include "usb_read_thread.hpp"
 #include "command_line_options.hpp"
 #include "xboxmsg.hpp"
 #include "helper.hpp"
@@ -92,10 +94,14 @@ Xbox360Controller::Xbox360Controller(struct usb_device* dev, bool is_guitar)
             }
         }
     }
+
+  read_thread = std::auto_ptr<USBReadThread>(new USBReadThread(handle, endpoint_in, 32));
+  read_thread->start_thread();
 }
 
 Xbox360Controller::~Xbox360Controller()
 {
+  read_thread->stop_thread();
   usb_release_interface(handle, 0); 
   usb_close(handle);
 }
@@ -167,7 +173,16 @@ bool
 Xbox360Controller::read(XboxGenericMsg& msg, bool verbose, int timeout)
 {
   uint8_t data[32];
-  int ret = usb_interrupt_read(handle, endpoint_in, (char*)data, sizeof(data), timeout);
+  int ret = 0;
+
+  if (read_thread.get())
+    {
+      ret = read_thread->read(data, sizeof(data));
+    }
+  else
+    {
+      ret = usb_interrupt_read(handle, endpoint_in, (char*)data, sizeof(data), timeout);
+    }
 
   if (ret == -ETIMEDOUT)
     {
diff --git a/src/xbox360_controller.hpp b/src/xbox360_controller.hpp
index b2b8fab..677a029 100644
--- a/src/xbox360_controller.hpp
+++ b/src/xbox360_controller.hpp
@@ -22,6 +22,7 @@
 #include <usb.h>
 #include "xbox_generic_controller.hpp"
 
+class USBReadThread;
 struct XPadDevice;
 
 /** */
@@ -36,6 +37,8 @@ private:
   int endpoint_in;
   int endpoint_out;
 
+  std::auto_ptr<USBReadThread> read_thread;
+
   void find_endpoints();
 
 public:
diff --git a/src/xbox360_wireless_controller.cpp b/src/xbox360_wireless_controller.cpp
index 88c84a9..691ac77 100644
--- a/src/xbox360_wireless_controller.cpp
+++ b/src/xbox360_wireless_controller.cpp
@@ -58,10 +58,12 @@ Xbox360WirelessController::Xbox360WirelessController(struct usb_device* dev,
     }
 
   read_thread = std::auto_ptr<USBReadThread>(new USBReadThread(handle, endpoint, 32));
+  read_thread->start_thread();
 }
 
 Xbox360WirelessController::~Xbox360WirelessController()
 {
+  read_thread->stop_thread();
   usb_release_interface(handle, interface); 
   usb_close(handle);
 }