logic: fixed crash when calling message listeners that already have been destroyed
* prevented lambda created by MessageQueue::sendMessageAsTask to call functions on message listeners that already have been destroyed.
This commit is contained in:
@@ -283,6 +283,7 @@ add_files(
|
||||
utility/messaging/Message.h
|
||||
utility/messaging/MessageBase.h
|
||||
utility/messaging/MessageListener.h
|
||||
utility/messaging/MessageListenerBase.cpp
|
||||
utility/messaging/MessageListenerBase.h
|
||||
utility/messaging/MessageQueue.cpp
|
||||
utility/messaging/MessageQueue.h
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
#include "utility/messaging/MessageListenerBase.h"
|
||||
|
||||
uint MessageListenerBase::s_nextId = 0;
|
||||
@@ -5,11 +5,13 @@
|
||||
|
||||
#include "utility/messaging/MessageBase.h"
|
||||
#include "utility/messaging/MessageQueue.h"
|
||||
#include "utility/types.h"
|
||||
|
||||
class MessageListenerBase
|
||||
{
|
||||
public:
|
||||
MessageListenerBase()
|
||||
: m_id(s_nextId++)
|
||||
{
|
||||
MessageQueue::getInstance()->registerListener(this);
|
||||
}
|
||||
@@ -19,9 +21,19 @@ public:
|
||||
MessageQueue::getInstance()->unregisterListener(this);
|
||||
}
|
||||
|
||||
uint getId() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
virtual std::string getType() const = 0;
|
||||
|
||||
virtual void handleMessageBase(MessageBase*) = 0;
|
||||
|
||||
private:
|
||||
static uint s_nextId;
|
||||
|
||||
uint m_id;
|
||||
};
|
||||
|
||||
#endif // MESSAGE_LISTENER_BASE_H
|
||||
|
||||
@@ -53,6 +53,19 @@ void MessageQueue::unregisterListener(MessageListenerBase* listener)
|
||||
LOG_ERROR("Listener was not found");
|
||||
}
|
||||
|
||||
MessageListenerBase* MessageQueue::getListenerById(const uint id) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_listenersMutex);
|
||||
for (size_t i = 0; i < m_listeners.size(); i++)
|
||||
{
|
||||
if (m_listeners[i]->getId() == id)
|
||||
{
|
||||
return m_listeners[i];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void MessageQueue::pushMessage(std::shared_ptr<MessageBase> message)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_backMessageBufferMutex);
|
||||
@@ -240,10 +253,15 @@ void MessageQueue::sendMessageAsTask(std::shared_ptr<MessageBase> message, bool
|
||||
|
||||
if (listener->getType() == message->getType())
|
||||
{
|
||||
uint listenerId = listener->getId();
|
||||
taskGroup->addTask(std::make_shared<LambdaTask>(
|
||||
[listener, message]()
|
||||
[listenerId, message]()
|
||||
{
|
||||
listener->handleMessageBase(message.get());
|
||||
MessageListenerBase* listener = MessageQueue::getInstance()->getListenerById(listenerId);
|
||||
if (listener)
|
||||
{
|
||||
listener->handleMessageBase(message.get());
|
||||
}
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
|
||||
#include "utility/types.h"
|
||||
|
||||
class MessageBase;
|
||||
class MessageListenerBase;
|
||||
|
||||
@@ -16,6 +18,8 @@ public:
|
||||
void registerListener(MessageListenerBase* listener);
|
||||
void unregisterListener(MessageListenerBase* listener);
|
||||
|
||||
MessageListenerBase* getListenerById(const uint id) const;
|
||||
|
||||
void pushMessage(std::shared_ptr<MessageBase> message);
|
||||
void processMessage(std::shared_ptr<MessageBase> message, bool asNextTask);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user