Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorr.kuznetsov <r.kuznetsov@corp.mail.ru>2018-07-18 19:00:48 +0300
committerVlad Mihaylenko <vxmihaylenko@gmail.com>2018-07-20 14:51:41 +0300
commit18b40387576e97b20bfb7f6273ee06be14458759 (patch)
tree1838754cd159da440c9db47bf72b6b636e3ce160 /drape_frontend
parentc6c1d7729d42cd2d145e7d2ede00117e96a6c953 (diff)
Fixed data race in filter messages
Diffstat (limited to 'drape_frontend')
-rw-r--r--drape_frontend/message_acceptor.cpp21
-rw-r--r--drape_frontend/message_acceptor.hpp11
-rw-r--r--drape_frontend/message_queue.cpp32
-rw-r--r--drape_frontend/message_queue.hpp11
4 files changed, 38 insertions, 37 deletions
diff --git a/drape_frontend/message_acceptor.cpp b/drape_frontend/message_acceptor.cpp
index 4f05bcdb06..7640c848b4 100644
--- a/drape_frontend/message_acceptor.cpp
+++ b/drape_frontend/message_acceptor.cpp
@@ -4,11 +4,9 @@
namespace df
{
-
MessageAcceptor::MessageAcceptor()
: m_infinityWaiting(false)
-{
-}
+{}
bool MessageAcceptor::ProcessSingleMessage(bool waitForMessage)
{
@@ -23,25 +21,19 @@ bool MessageAcceptor::ProcessSingleMessage(bool waitForMessage)
return true;
}
-void MessageAcceptor::EnableMessageFiltering(TFilterMessageFn needFilterMessageFn)
+void MessageAcceptor::EnableMessageFiltering(MessageQueue::FilterMessageFn && filter)
{
- ASSERT(needFilterMessageFn != nullptr, ());
-
- m_needFilterMessageFn = needFilterMessageFn;
- m_messageQueue.FilterMessages(needFilterMessageFn);
+ m_messageQueue.EnableMessageFiltering(std::move(filter));
}
void MessageAcceptor::DisableMessageFiltering()
{
- m_needFilterMessageFn = nullptr;
+ m_messageQueue.DisableMessageFiltering();
}
void MessageAcceptor::PostMessage(drape_ptr<Message> && message, MessagePriority priority)
{
- if (m_needFilterMessageFn != nullptr && m_needFilterMessageFn(make_ref(message)))
- return;
-
- m_messageQueue.PushMessage(move(message), priority);
+ m_messageQueue.PushMessage(std::move(message), priority);
}
void MessageAcceptor::CloseQueue()
@@ -73,5 +65,4 @@ size_t MessageAcceptor::GetQueueSize() const
}
#endif
-
-} // namespace df
+} // namespace df
diff --git a/drape_frontend/message_acceptor.hpp b/drape_frontend/message_acceptor.hpp
index 32f8989df8..0d168e9b7d 100644
--- a/drape_frontend/message_acceptor.hpp
+++ b/drape_frontend/message_acceptor.hpp
@@ -5,18 +5,18 @@
#include "drape/pointers.hpp"
#include <atomic>
+#include <mutex>
#include <functional>
namespace df
{
-
class Message;
class MessageAcceptor
{
protected:
MessageAcceptor();
- virtual ~MessageAcceptor(){}
+ virtual ~MessageAcceptor() = default;
virtual void AcceptMessage(ref_ptr<Message> message) = 0;
@@ -34,8 +34,7 @@ protected:
size_t GetQueueSize() const;
#endif
- using TFilterMessageFn = std::function<bool(ref_ptr<Message>)>;
- void EnableMessageFiltering(TFilterMessageFn needFilterMessageFn);
+ void EnableMessageFiltering(MessageQueue::FilterMessageFn && filter);
void DisableMessageFiltering();
private:
@@ -45,7 +44,5 @@ private:
MessageQueue m_messageQueue;
std::atomic<bool> m_infinityWaiting;
- TFilterMessageFn m_needFilterMessageFn;
};
-
-} // namespace df
+} // namespace df
diff --git a/drape_frontend/message_queue.cpp b/drape_frontend/message_queue.cpp
index f88bbd1609..ee1c46950e 100644
--- a/drape_frontend/message_queue.cpp
+++ b/drape_frontend/message_queue.cpp
@@ -5,11 +5,9 @@
namespace df
{
-
MessageQueue::MessageQueue()
: m_isWaiting(false)
-{
-}
+{}
MessageQueue::~MessageQueue()
{
@@ -46,6 +44,9 @@ void MessageQueue::PushMessage(drape_ptr<Message> && message, MessagePriority pr
{
std::lock_guard<std::mutex> lock(m_mutex);
+ if (m_filter != nullptr && m_filter(make_ref(message)))
+ return;
+
switch (priority)
{
case MessagePriority::Normal:
@@ -90,14 +91,13 @@ void MessageQueue::PushMessage(drape_ptr<Message> && message, MessagePriority pr
CancelWaitImpl();
}
-void MessageQueue::FilterMessages(TFilterMessageFn needFilterMessageFn)
+void MessageQueue::FilterMessagesImpl()
{
- ASSERT(needFilterMessageFn != nullptr, ());
+ CHECK(m_filter != nullptr, ());
- std::lock_guard<std::mutex> lock(m_mutex);
for (auto it = m_messages.begin(); it != m_messages.end(); )
{
- if (needFilterMessageFn(make_ref(it->first)))
+ if (m_filter(make_ref(it->first)))
it = m_messages.erase(it);
else
++it;
@@ -105,13 +105,26 @@ void MessageQueue::FilterMessages(TFilterMessageFn needFilterMessageFn)
for (auto it = m_lowPriorityMessages.begin(); it != m_lowPriorityMessages.end(); )
{
- if (needFilterMessageFn(make_ref(*it)))
+ if (m_filter(make_ref(*it)))
it = m_lowPriorityMessages.erase(it);
else
++it;
}
}
+void MessageQueue::EnableMessageFiltering(FilterMessageFn && filter)
+{
+ std::lock_guard<std::mutex> lock(m_mutex);
+ m_filter = std::move(filter);
+ FilterMessagesImpl();
+}
+
+void MessageQueue::DisableMessageFiltering()
+{
+ std::lock_guard<std::mutex> lock(m_mutex);
+ m_filter = nullptr;
+}
+
#ifdef DEBUG_MESSAGE_QUEUE
bool MessageQueue::IsEmpty() const
@@ -148,5 +161,4 @@ void MessageQueue::ClearQuery()
m_messages.clear();
m_lowPriorityMessages.clear();
}
-
-} // namespace df
+} // namespace df
diff --git a/drape_frontend/message_queue.hpp b/drape_frontend/message_queue.hpp
index 93e8d44d31..b491e0d6b5 100644
--- a/drape_frontend/message_queue.hpp
+++ b/drape_frontend/message_queue.hpp
@@ -13,7 +13,6 @@
namespace df
{
-
//#define DEBUG_MESSAGE_QUEUE
class MessageQueue
@@ -28,8 +27,9 @@ public:
void CancelWait();
void ClearQuery();
- using TFilterMessageFn = std::function<bool(ref_ptr<Message>)>;
- void FilterMessages(TFilterMessageFn needFilterMessageFn);
+ using FilterMessageFn = std::function<bool(ref_ptr<Message>)>;
+ void EnableMessageFiltering(FilterMessageFn && filter);
+ void DisableMessageFiltering();
#ifdef DEBUG_MESSAGE_QUEUE
bool IsEmpty() const;
@@ -37,6 +37,7 @@ public:
#endif
private:
+ void FilterMessagesImpl();
void CancelWaitImpl();
mutable std::mutex m_mutex;
@@ -45,6 +46,6 @@ private:
using TMessageNode = std::pair<drape_ptr<Message>, MessagePriority>;
std::deque<TMessageNode> m_messages;
std::deque<drape_ptr<Message>> m_lowPriorityMessages;
+ FilterMessageFn m_filter;
};
-
-} // namespace df
+} // namespace df