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:
pixl 2020-07-11 19:04:19 -04:00
parent 0fbeb1e3c9
commit de8e453bd3
No known key found for this signature in database
GPG Key ID: 1866C148CD593B6E
4 changed files with 18 additions and 7 deletions

View File

@ -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()) {

View File

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

View File

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

View File

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