From 5ee51d38575f289c2bf37ed817ef680ed47bb320 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Bollo?= Date: Fri, 1 Feb 2019 15:37:44 +0100 Subject: [PATCH 12/14] Avoid casting from "const T&" to "void*" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Latest version of g++ refuse the cast reinterpret_cast(serviceFunction) I made no investigation to know if the problem is coming from the const or not. Signed-off-by: José Bollo --- src/server/main/include/service-thread.h | 42 ++++++++++-------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/src/server/main/include/service-thread.h b/src/server/main/include/service-thread.h index 964d168..61fdda8 100644 --- a/src/server/main/include/service-thread.h +++ b/src/server/main/include/service-thread.h @@ -94,7 +94,7 @@ public: Join(); while (!m_eventQueue.empty()){ auto front = m_eventQueue.front(); - delete front.eventPtr; + delete front; m_eventQueue.pop(); } } @@ -104,34 +104,28 @@ public: Service *servicePtr, void (Service::*serviceFunction)(const T &)) { - EventDescription description; - description.serviceFunctionPtr = - reinterpret_cast(serviceFunction); - description.servicePtr = servicePtr; - description.eventFunctionPtr = &ServiceThread::EventCall; - description.eventPtr = new T(event); + EventCallerBase *ec = new EventCaller(event, servicePtr, serviceFunction); { std::lock_guard lock(m_eventQueueMutex); - m_eventQueue.push(description); + m_eventQueue.push(ec); } m_waitCondition.notify_one(); } protected: - struct EventDescription { - void (Service::*serviceFunctionPtr)(void *); - Service *servicePtr; - void (ServiceThread::*eventFunctionPtr)(const EventDescription &event); - GenericEvent* eventPtr; + struct EventCallerBase { + virtual void fire() = 0; + virtual ~EventCallerBase() {} }; template - void EventCall(const EventDescription &desc) { - auto fun = reinterpret_cast(desc.serviceFunctionPtr); - const T& eventLocale = *(static_cast(desc.eventPtr)); - (desc.servicePtr->*fun)(eventLocale); - } + struct EventCaller : public EventCallerBase { + T *event; Service *target; void (Service::*function)(const T&); + EventCaller(const T &e, Service *c, void (Service::*f)(const T&)) : event(new T(e)), target(c), function(f) {} + ~EventCaller() { delete event; } + void fire() { (target->*function)(*event); } + }; static void ThreadLoopStatic(ServiceThread *ptr) { ptr->ThreadLoop(); @@ -139,33 +133,33 @@ protected: void ThreadLoop(){ for (;;) { - EventDescription description = {NULL, NULL, NULL, NULL}; + EventCallerBase *ec = NULL; { std::unique_lock ulock(m_eventQueueMutex); if (m_quit) return; if (!m_eventQueue.empty()) { - description = m_eventQueue.front(); + ec = m_eventQueue.front(); m_eventQueue.pop(); } else { m_waitCondition.wait(ulock); } } - if (description.eventPtr != NULL) { + if (ec != NULL) { UNHANDLED_EXCEPTION_HANDLER_BEGIN { - (this->*description.eventFunctionPtr)(description); - delete description.eventPtr; + ec->fire(); } UNHANDLED_EXCEPTION_HANDLER_END + delete ec; } } } std::thread m_thread; std::mutex m_eventQueueMutex; - std::queue m_eventQueue; + std::queue m_eventQueue; std::condition_variable m_waitCondition; State m_state; -- 2.21.0