Fix deadlock issue
RawDevice would deadlock in some situations because I/O occured while the listener was turning on. This also seems to have fixed logid sometimes not detecting devices on receivers.
This commit is contained in:
parent
0fbeb1e3c9
commit
de8e453bd3
|
@ -325,9 +325,7 @@ void Receiver::listen()
|
||||||
{
|
{
|
||||||
if(!_raw_device->isListening())
|
if(!_raw_device->isListening())
|
||||||
///TODO: Kill RawDevice?
|
///TODO: Kill RawDevice?
|
||||||
thread::spawn({[raw=this->_raw_device]() {
|
_raw_device->listenAsync();
|
||||||
raw->listen();
|
|
||||||
}});
|
|
||||||
|
|
||||||
if(_raw_device->eventHandlers().find("RECV_HIDPP") ==
|
if(_raw_device->eventHandlers().find("RECV_HIDPP") ==
|
||||||
_raw_device->eventHandlers().end()) {
|
_raw_device->eventHandlers().end()) {
|
||||||
|
|
|
@ -200,9 +200,7 @@ uint16_t Device::pid() const
|
||||||
void Device::listen()
|
void Device::listen()
|
||||||
{
|
{
|
||||||
if(!_raw_device->isListening())
|
if(!_raw_device->isListening())
|
||||||
thread::spawn({[raw=this->_raw_device]() {
|
_raw_device->listenAsync();
|
||||||
raw->listen();
|
|
||||||
}});
|
|
||||||
|
|
||||||
// Pass all HID++ events with device index to this device.
|
// Pass all HID++ events with device index to this device.
|
||||||
auto handler = std::make_shared<raw::RawEventHandler>();
|
auto handler = std::make_shared<raw::RawEventHandler>();
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "../../util/log.h"
|
#include "../../util/log.h"
|
||||||
#include "../hidpp/Report.h"
|
#include "../hidpp/Report.h"
|
||||||
#include "../../Configuration.h"
|
#include "../../Configuration.h"
|
||||||
|
#include "../../util/thread.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
|
@ -327,8 +328,8 @@ void RawDevice::interruptRead()
|
||||||
void RawDevice::listen()
|
void RawDevice::listen()
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(_listening);
|
std::lock_guard<std::mutex> lock(_listening);
|
||||||
|
|
||||||
_continue_listen = true;
|
_continue_listen = true;
|
||||||
|
_listen_condition.notify_all();
|
||||||
while(_continue_listen) {
|
while(_continue_listen) {
|
||||||
while(!_io_queue.empty()) {
|
while(!_io_queue.empty()) {
|
||||||
auto task = _io_queue.front();
|
auto task = _io_queue.front();
|
||||||
|
@ -351,6 +352,18 @@ void RawDevice::listen()
|
||||||
_continue_listen = false;
|
_continue_listen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RawDevice::listenAsync()
|
||||||
|
{
|
||||||
|
std::mutex listen_check;
|
||||||
|
std::unique_lock<std::mutex> check_lock(listen_check);
|
||||||
|
thread::spawn({[this]() { listen(); }});
|
||||||
|
|
||||||
|
// Block until RawDevice is listening
|
||||||
|
_listen_condition.wait(check_lock, [this](){
|
||||||
|
return (bool)_continue_listen;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void RawDevice::stopListener()
|
void RawDevice::stopListener()
|
||||||
{
|
{
|
||||||
_continue_listen = false;
|
_continue_listen = false;
|
||||||
|
|
|
@ -54,6 +54,7 @@ namespace raw
|
||||||
void interruptRead();
|
void interruptRead();
|
||||||
|
|
||||||
void listen();
|
void listen();
|
||||||
|
void listenAsync();
|
||||||
void stopListener();
|
void stopListener();
|
||||||
bool isListening();
|
bool isListening();
|
||||||
|
|
||||||
|
@ -74,6 +75,7 @@ namespace raw
|
||||||
std::vector<uint8_t> rdesc;
|
std::vector<uint8_t> rdesc;
|
||||||
|
|
||||||
std::atomic<bool> _continue_listen;
|
std::atomic<bool> _continue_listen;
|
||||||
|
std::condition_variable _listen_condition;
|
||||||
|
|
||||||
std::map<std::string, std::shared_ptr<RawEventHandler>>
|
std::map<std::string, std::shared_ptr<RawEventHandler>>
|
||||||
_event_handlers;
|
_event_handlers;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user