Some experimental work on using threads for reading from USB

This commit is contained in:
Ingo Ruhnke 2009-07-29 15:43:23 +02:00
parent bcda1f82ae
commit d047b207ee
2 changed files with 159 additions and 0 deletions

96
src/usb_read_thread.cpp Normal file
View file

@ -0,0 +1,96 @@
/*
** Xbox/Xbox360 USB Gamepad Userspace Driver
** Copyright (C) 2008 Ingo Ruhnke <grumbel@gmx.de>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <boost/thread/thread.hpp>
#include <usb.h>
#include "usb_read_thread.hpp"
USBReadThread::USBReadThread(struct usb_dev_handle* handle, int endpoint, int len) :
m_handle(handle),
m_read_endpoint(endpoint),
m_read_length(len),
m_stop(false)
{
}
USBReadThread::~USBReadThread()
{
}
void
USBReadThread::start_thread()
{
m_stop = false;
m_thread = boost::thread(boost::bind(&USBReadThread::run, this));
}
void
USBReadThread::stop_thread()
{
m_stop = true;
m_thread.join();
}
int
USBReadThread::read(uint8_t* data, int len)
{
boost::mutex::scoped_lock lock(m_read_buffer_mutex);
if (m_read_buffer.empty())
{
return 0;
}
else
{
assert(len == m_read_length);
Paket& paket = m_read_buffer.front();
memcpy(data, paket.data, m_read_length);
delete[] paket.data;
int ret = paket.length;
m_read_buffer.pop_front();
return ret;
}
}
void
USBReadThread::run()
{
while(!m_stop)
{
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*/);
{
boost::mutex::scoped_lock lock(m_read_buffer_mutex);
Paket paket;
paket.data = data;
paket.length = ret;
m_read_buffer.push_back(paket);
}
}
}
/* EOF */

63
src/usb_read_thread.hpp Normal file
View file

@ -0,0 +1,63 @@
/*
** Windstille - A Sci-Fi Action-Adventure Game
** Copyright (C) 2009 Ingo Ruhnke <grumbel@gmx.de>
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef HEADER_USB_READ_THREAD_HPP
#define HEADER_USB_READ_THREAD_HPP
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
#include <list>
class USBReadThread
{
private:
struct usb_dev_handle* m_handle;
const int m_read_endpoint;
const int m_read_length;
struct Paket {
uint8_t* data;
int length;
};
std::list<Paket> m_read_buffer;
boost::mutex m_read_buffer_mutex;
boost::thread m_thread;
bool m_stop;
public:
USBReadThread(struct usb_dev_handle* handle, int endpoint, int len);
~USBReadThread();
int read(uint8_t* data, int len);
void start_thread();
void stop_thread();
private:
void run();
private:
USBReadThread(const USBReadThread&);
USBReadThread& operator=(const USBReadThread&);
};
#endif
/* EOF */