From bb8f87267b3c4d7425c244e0c098b931ff2d576c Mon Sep 17 00:00:00 2001 From: mitchellhansen Date: Wed, 21 Feb 2018 21:02:08 -0800 Subject: [PATCH] Fixed a segfault on shutdown --- include/CLCaster.h | 2 +- include/Gui.h | 1 - include/Pub_Sub.h | 33 ++++++++++++++++++++++----------- src/Pub_Sub.cpp | 25 ++++++++++++++++++------- 4 files changed, 41 insertions(+), 20 deletions(-) diff --git a/include/CLCaster.h b/include/CLCaster.h index b1db061..67c9138 100644 --- a/include/CLCaster.h +++ b/include/CLCaster.h @@ -177,7 +177,7 @@ private: /** * Device is a storage container for device data we retrieve from OpenCL * - * The data is mainly queries as strings or integer types and stored into + * The data are mainly queries as strings or integer types and stored into * respective containers. We store this data into a file and retrieve it later * to let users select a preferred compute device and keep track of their choice */ diff --git a/include/Gui.h b/include/Gui.h index 1cd5ef6..2a0a44c 100644 --- a/include/Gui.h +++ b/include/Gui.h @@ -49,7 +49,6 @@ private: } }; - static std::mutex container_lock; static std::list renderable_container; diff --git a/include/Pub_Sub.h b/include/Pub_Sub.h index 98f5ba6..13ba4ef 100644 --- a/include/Pub_Sub.h +++ b/include/Pub_Sub.h @@ -3,6 +3,7 @@ #include #include "Event.hpp" #include +#include class VrEventPublisher; @@ -13,14 +14,6 @@ class VrEventPublisher; * * VrEventSubscriber * - * When inherited, the user must impliment a - * - * - * - * - * - * - * */ @@ -28,16 +21,25 @@ class VrEventPublisher; class VrEventSubscriber { public: virtual ~VrEventSubscriber(); + + // Recieve an event from a publisher, event must be cast to it's respective event type virtual void event_handler(VrEventPublisher *publisher, std::unique_ptr event) = 0; + + // Subscribes to the publisher, keeps track of the ptr and the relevent event types void subscribe_to_publisher(VrEventPublisher* publisher, vr::Event::EventType type); void subscribe_to_publisher(VrEventPublisher* publisher, std::vector type); - void unsubscribe(VrEventPublisher* publisher, vr::Event::EventType type); + + // Looks for the publisher ptr and event type in the subscriptions map. If there, Removes them + void unsubscribe(VrEventPublisher* publisher, vr::Event::EventType type); + void unsubscribe_all(VrEventPublisher* publisher); + void unsubscribe_all(); + protected: // When we destroy a subscriber we need to be able to notify the publishers // We have to keep track of every EventType because of the way EventTypes // are mapped to subscribers in the publisher - std::map> subscriptions; + std::map> subscriptions; }; @@ -45,11 +47,20 @@ class VrEventPublisher { public: virtual ~VrEventPublisher(); + + // Adds the subscriber ptr to the bucket[event_type] virtual void subscribe(VrEventSubscriber *subscriber, vr::Event::EventType type); virtual void subscribe(VrEventSubscriber *subscriber, std::vector type); - virtual void unsubscribe(VrEventSubscriber *s, vr::Event::EventType c); + + // Removes the subscriber ptr from the specified bucket[type] + // If subscribed to multiple events, unsubscribe must be called for each event + virtual void unsubscribe(VrEventSubscriber *s, vr::Event::EventType c); + + // Trigger the publisher to notify it's subscribers to the specified event virtual void notify_subscribers(std::unique_ptr event); + private: + std::map> subscribers; }; diff --git a/src/Pub_Sub.cpp b/src/Pub_Sub.cpp index 4cd5dd3..d8168b2 100644 --- a/src/Pub_Sub.cpp +++ b/src/Pub_Sub.cpp @@ -6,7 +6,6 @@ /** * Subscriber */ - VrEventSubscriber::~VrEventSubscriber() { // Cycles through the publishers we're subscribed to @@ -23,18 +22,30 @@ void VrEventSubscriber::subscribe_to_publisher(VrEventPublisher* publisher, vr:: publisher->subscribe(this, type); - subscriptions[publisher].push_back(type); + subscriptions[publisher].insert(type); } void VrEventSubscriber::subscribe_to_publisher(VrEventPublisher* publisher, std::vector type) { publisher->subscribe(this, type); - subscriptions[publisher].insert(subscriptions[publisher].end(), type.begin(), type.end()); + subscriptions[publisher].insert(type.begin(), type.end()); } void VrEventSubscriber::unsubscribe(VrEventPublisher* publisher, vr::Event::EventType type){ + if (subscriptions.count(publisher)){ + std::set set = subscriptions[publisher]; + auto it = set.find (type); + set.erase (it, set.end()); + } +} + +void VrEventSubscriber::unsubscribe_all(VrEventPublisher* publisher){ + + if (subscriptions.count(publisher)){ + subscriptions.erase(publisher); + } } /** @@ -43,11 +54,11 @@ void VrEventSubscriber::unsubscribe(VrEventPublisher* publisher, vr::Event::Even VrEventPublisher::~VrEventPublisher() { // Cycle through the subscribers that are listening to us - for (auto const& subscriber_bucket : subscribers) { + for (auto const& event_bucket : subscribers) { - // And one by one remove the - for (auto subscriber: subscriber_bucket.second){ - //subscriber. + // And one by one remove the subscriber + for (auto subscriber: event_bucket.second){ + subscriber->unsubscribe(this, event_bucket.first); } } }