c++ - How to implement the observer pattern safely? -


i'm implementing mechanism similar observer design pattern multithreaded tetris game. there game class contains collection of eventhandler objects. if class wants register listener game object must inherit game::eventhandler class. on state change events corresponing method called on eventhandler interface of each listener. code looks like:

class game { public:     class eventhandler     {     public:         eventhandler();          virtual ~eventhandler();          virtual void ongamestatechanged(game * ingame) = 0;          virtual void onlinescleared(game * ingame, int inlinecount) = 0;      private:         eventhandler(const eventhandler&);         eventhandler& operator=(const eventhandler&);     };      static void registereventhandler(threadsafe<game> ingame, eventhandler * ineventhandler);      static void unregistereventhandler(threadsafe<game> ingame, eventhandler * ineventhandler);      typedef std::set<eventhandler*> eventhandlers;     eventhandlers meventhandlers;  private:         typedef std::set<game*> instances;     static instances sinstances; };   void game::registereventhandler(threadsafe<game> ingame, eventhandler * ineventhandler) {     scopedreaderandwriter<game> rwgame(ingame);     game * game(rwgame.get());     if (sinstances.find(game) == sinstances.end())     {         logwarning("game::registereventhandler: game object not exist!");         return;     }      game->meventhandlers.insert(ineventhandler); }   void game::unregistereventhandler(threadsafe<game> ingame, eventhandler * ineventhandler) {     scopedreaderandwriter<game> rwgame(ingame);     game * game(rwgame.get());     if (sinstances.find(game) == sinstances.end())     {         logwarning("game::unregistereventhandler: game object no longer exists!");         return;     }      game->meventhandlers.erase(ineventhandler); } 

there 2 problems experience kind of pattern:

  1. a listener object wants unregister on deleted object resulting in crash.
  2. a event fired listener no longer exists. happens in multithreaded code. here's typical scenario:
    • the game state changes in worker thread. want notification occur in main thread.
    • the event wrapped in boost::function , sent postmessage main thread.
    • a short time later function object processed main thread while game object deleted. result crash.

my current workaround 1 can see in above code sample. made unregistereventhandler static method checks against list of instances. help, find hackish solution.

does know of set of guidelines on how cleanly , safely implement notifier/listener system? advice on how avoid above pitfalls?

ps: if need more information in order answer question can find relevant code online here: game.h, game.cpp, simplegame.h, simplegame.cpp, mainwindow.cpp.

  1. the rule of thumb delete , new object should near each other. e.g. in constructor , destructor or before , after call use object. it's bad practice delete object in object when latter 1 didn't create former one.

  2. i don't understand how pack events. seems have check whether game still alive before processing event. or can use shared_ptr in events , other places sure games deleted last.


Comments

Popular posts from this blog

javascript - Enclosure Memory Copies -

php - Replacing tags in braces, even nested tags, with regex -