Added more mutexes in eventmanager, fixed exiting destruction bug
parent
9629864f1b
commit
ef16e60025
|
|
@ -3,20 +3,32 @@
|
||||||
|
|
||||||
using namespace icsneo;
|
using namespace icsneo;
|
||||||
|
|
||||||
static std::unique_ptr<EventManager> singleton;
|
|
||||||
|
|
||||||
EventManager& EventManager::GetInstance() {
|
EventManager& EventManager::GetInstance() {
|
||||||
if(!singleton)
|
static EventManager inst;
|
||||||
singleton = std::unique_ptr<EventManager>(new EventManager());
|
return inst;
|
||||||
return *singleton.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventManager::ResetInstance() {
|
void EventManager::ResetInstance() {
|
||||||
singleton = std::unique_ptr<EventManager>(new EventManager());
|
std::lock_guard<std::mutex> eventsLock(eventsMutex);
|
||||||
|
std::lock_guard<std::mutex> errorsLock(errorsMutex);
|
||||||
|
std::lock_guard<std::mutex> downgradedThreadsLock(downgradedThreadsMutex);
|
||||||
|
std::lock_guard<std::mutex> callbacksLock(callbacksMutex);
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> callbackIDLock(callbackIDMutex);
|
||||||
|
std::lock_guard<std::mutex> eventLimitLock(eventLimitMutex);
|
||||||
|
|
||||||
|
events.clear();
|
||||||
|
lastUserErrors.clear();
|
||||||
|
downgradedThreads.clear();
|
||||||
|
callbacks.clear();
|
||||||
|
|
||||||
|
callbackID = 0;
|
||||||
|
eventLimit = 10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
int EventManager::addEventCallback(const EventCallback &cb) {
|
int EventManager::addEventCallback(const EventCallback &cb) {
|
||||||
std::lock_guard<std::mutex> lk(callbacksMutex);
|
std::lock_guard<std::mutex> callbacksLock(callbacksMutex);
|
||||||
|
std::lock_guard<std::mutex> callbackIDLock(callbackIDMutex);
|
||||||
callbacks.insert({callbackID, cb});
|
callbacks.insert({callbackID, cb});
|
||||||
return callbackID++;
|
return callbackID++;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#include "icsneo/device/device.h"
|
#include "icsneo/device/device.h"
|
||||||
#include "icsneo/communication/message/callback/messagecallback.h"
|
#include "icsneo/communication/message/callback/messagecallback.h"
|
||||||
|
#include "icsneo/api/eventmanager.h"
|
||||||
#include "icsneo/communication/command.h"
|
#include "icsneo/communication/command.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,19 @@ typedef std::function<void (APIEvent::Type, APIEvent::Severity)> device_eventhan
|
||||||
|
|
||||||
class EventManager {
|
class EventManager {
|
||||||
public:
|
public:
|
||||||
|
~EventManager() {
|
||||||
|
destructing = true;
|
||||||
|
}
|
||||||
|
|
||||||
static EventManager& GetInstance();
|
static EventManager& GetInstance();
|
||||||
|
|
||||||
static void ResetInstance();
|
void ResetInstance();
|
||||||
|
|
||||||
// If this thread is not in the map, add it to be ignored
|
// If this thread is not in the map, add it to be ignored
|
||||||
// If it is, set it to be ignored
|
// If it is, set it to be ignored
|
||||||
void downgradeErrorsOnCurrentThread() {
|
void downgradeErrorsOnCurrentThread() {
|
||||||
|
if(destructing)
|
||||||
|
return;
|
||||||
std::lock_guard<std::mutex> lk(downgradedThreadsMutex);
|
std::lock_guard<std::mutex> lk(downgradedThreadsMutex);
|
||||||
auto i = downgradedThreads.find(std::this_thread::get_id());
|
auto i = downgradedThreads.find(std::this_thread::get_id());
|
||||||
if(i != downgradedThreads.end()) {
|
if(i != downgradedThreads.end()) {
|
||||||
|
|
@ -35,6 +41,8 @@ public:
|
||||||
|
|
||||||
// If this thread exists in the map, turn off downgrading
|
// If this thread exists in the map, turn off downgrading
|
||||||
void cancelErrorDowngradingOnCurrentThread() {
|
void cancelErrorDowngradingOnCurrentThread() {
|
||||||
|
if(destructing)
|
||||||
|
return;
|
||||||
std::lock_guard<std::mutex> lk(downgradedThreadsMutex);
|
std::lock_guard<std::mutex> lk(downgradedThreadsMutex);
|
||||||
auto i = downgradedThreads.find(std::this_thread::get_id());
|
auto i = downgradedThreads.find(std::this_thread::get_id());
|
||||||
if(i != downgradedThreads.end()) {
|
if(i != downgradedThreads.end()) {
|
||||||
|
|
@ -63,6 +71,8 @@ public:
|
||||||
APIEvent getLastError();
|
APIEvent getLastError();
|
||||||
|
|
||||||
void add(APIEvent event) {
|
void add(APIEvent event) {
|
||||||
|
if(destructing)
|
||||||
|
return;
|
||||||
if(event.getSeverity() == APIEvent::Severity::Error) {
|
if(event.getSeverity() == APIEvent::Severity::Error) {
|
||||||
// if the error was added on a thread that downgrades errors (non-user thread)
|
// if the error was added on a thread that downgrades errors (non-user thread)
|
||||||
std::lock_guard<std::mutex> lk(downgradedThreadsMutex);
|
std::lock_guard<std::mutex> lk(downgradedThreadsMutex);
|
||||||
|
|
@ -93,7 +103,7 @@ public:
|
||||||
void discard(EventFilter filter = EventFilter());
|
void discard(EventFilter filter = EventFilter());
|
||||||
|
|
||||||
void setEventLimit(size_t newLimit) {
|
void setEventLimit(size_t newLimit) {
|
||||||
std::lock_guard<std::mutex> lk(eventsMutex);
|
std::lock_guard<std::mutex> eventLimitLock(eventLimitMutex);
|
||||||
|
|
||||||
if(newLimit == eventLimit)
|
if(newLimit == eventLimit)
|
||||||
return;
|
return;
|
||||||
|
|
@ -104,17 +114,19 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
eventLimit = newLimit;
|
eventLimit = newLimit;
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> eventsLock(eventsMutex);
|
||||||
if(enforceLimit())
|
if(enforceLimit())
|
||||||
add_internal_event(APIEvent(APIEvent::Type::TooManyEvents, APIEvent::Severity::EventWarning));
|
add_internal_event(APIEvent(APIEvent::Type::TooManyEvents, APIEvent::Severity::EventWarning));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t getEventLimit() const {
|
size_t getEventLimit() const {
|
||||||
std::lock_guard<std::mutex> lk(eventsMutex);
|
std::lock_guard<std::mutex> lk(eventLimitMutex);
|
||||||
return eventLimit;
|
return eventLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EventManager() : eventsMutex(), errorsMutex(), downgradedThreadsMutex(), callbacksMutex(), downgradedThreads(), callbacks(), events(), lastUserErrors(), eventLimit(10000) {}
|
EventManager() : eventsMutex(), errorsMutex(), downgradedThreadsMutex(), callbacksMutex(), callbackIDMutex(), eventLimitMutex(), downgradedThreads(), callbacks(), events(), lastUserErrors(), eventLimit(10000) {}
|
||||||
EventManager(const EventManager &other);
|
EventManager(const EventManager &other);
|
||||||
EventManager& operator=(const EventManager &other);
|
EventManager& operator=(const EventManager &other);
|
||||||
|
|
||||||
|
|
@ -124,12 +136,17 @@ private:
|
||||||
mutable std::mutex downgradedThreadsMutex;
|
mutable std::mutex downgradedThreadsMutex;
|
||||||
mutable std::mutex callbacksMutex;
|
mutable std::mutex callbacksMutex;
|
||||||
|
|
||||||
|
mutable std::mutex callbackIDMutex;
|
||||||
|
mutable std::mutex eventLimitMutex;
|
||||||
|
|
||||||
std::map<std::thread::id, bool> downgradedThreads;
|
std::map<std::thread::id, bool> downgradedThreads;
|
||||||
|
|
||||||
std::map<int, EventCallback> callbacks;
|
std::map<int, EventCallback> callbacks;
|
||||||
|
|
||||||
int callbackID = 0;
|
int callbackID = 0;
|
||||||
|
|
||||||
|
bool destructing = false;
|
||||||
|
|
||||||
// Stores all events
|
// Stores all events
|
||||||
std::list<APIEvent> events;
|
std::list<APIEvent> events;
|
||||||
std::map<std::thread::id, APIEvent> lastUserErrors;
|
std::map<std::thread::id, APIEvent> lastUserErrors;
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ namespace icsneo {
|
||||||
class Device {
|
class Device {
|
||||||
public:
|
public:
|
||||||
virtual ~Device() {
|
virtual ~Device() {
|
||||||
destructing = true;
|
|
||||||
if(isMessagePollingEnabled())
|
if(isMessagePollingEnabled())
|
||||||
disableMessagePolling();
|
disableMessagePolling();
|
||||||
close();
|
close();
|
||||||
|
|
@ -121,8 +120,7 @@ protected:
|
||||||
|
|
||||||
virtual device_eventhandler_t makeEventHandler() {
|
virtual device_eventhandler_t makeEventHandler() {
|
||||||
return [this](APIEvent::Type type, APIEvent::Severity severity) {
|
return [this](APIEvent::Type type, APIEvent::Severity severity) {
|
||||||
if(!destructing)
|
EventManager::GetInstance().add(type, severity, this);
|
||||||
EventManager::GetInstance().add(type, severity, this);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -178,8 +176,6 @@ private:
|
||||||
size_t pollingMessageLimit = 20000;
|
size_t pollingMessageLimit = 20000;
|
||||||
moodycamel::BlockingConcurrentQueue<std::shared_ptr<Message>> pollingContainer;
|
moodycamel::BlockingConcurrentQueue<std::shared_ptr<Message>> pollingContainer;
|
||||||
void enforcePollingMessageLimit();
|
void enforcePollingMessageLimit();
|
||||||
|
|
||||||
bool destructing = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ class EventManagerTest : public ::testing::Test {
|
||||||
protected:
|
protected:
|
||||||
// Start with a clean instance of eventmanager for every test
|
// Start with a clean instance of eventmanager for every test
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
EventManager::ResetInstance();
|
EventManager::GetInstance().ResetInstance();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue