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:
- a listener object wants unregister on deleted object resulting in crash.
- 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.
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.
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
Post a Comment