From eeb18ee6e3b1b07574a7f0fda2c0c20ac3f773df Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Wed, 11 Feb 2015 16:03:21 +0100 Subject: Ensure all dynrefs with the same target resolve to the same object when one name points to multiple objects --- src/modules.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/modules.cpp') diff --git a/src/modules.cpp b/src/modules.cpp index d7aa534ab..6510c9423 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -684,8 +684,10 @@ void dynamic_reference_base::SetProvider(const std::string& newname) void dynamic_reference_base::resolve() { - std::multimap::iterator i = ServerInstance->Modules->DataProviders.find(name); - if (i != ServerInstance->Modules->DataProviders.end()) + // Because find() may return any element with a matching key in case count(key) > 1 use lower_bound() + // to ensure a dynref with the same name as another one resolves to the same object + std::multimap::iterator i = ServerInstance->Modules.DataProviders.lower_bound(name); + if ((i != ServerInstance->Modules.DataProviders.end()) && (i->first == this->name)) value = static_cast(i->second); else value = NULL; -- cgit v1.2.3 From e37add3fab8f39b18a69453ee1533e09e7f156de Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Wed, 11 Feb 2015 16:06:47 +0100 Subject: Allow dynrefs to have an OnCapture() hook --- include/dynref.h | 16 ++++++++++++++++ src/modules.cpp | 12 ++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) (limited to 'src/modules.cpp') diff --git a/include/dynref.h b/include/dynref.h index a3d2f9966..2069a87eb 100644 --- a/include/dynref.h +++ b/include/dynref.h @@ -24,8 +24,18 @@ class CoreExport dynamic_reference_base : public interfacebase, public insp::intrusive_list_node { + public: + class CaptureHook + { + public: + /** Called when the target of the dynamic_reference has been acquired + */ + virtual void OnCapture() = 0; + }; + private: std::string name; + CaptureHook* hook; void resolve(); protected: ServiceProvider* value; @@ -35,6 +45,12 @@ class CoreExport dynamic_reference_base : public interfacebase, public insp::int ~dynamic_reference_base(); inline const std::string& GetProvider() { return name; } void SetProvider(const std::string& newname); + + /** Set handler to call when the target object becomes available + * @param h Handler to call + */ + void SetCaptureHook(CaptureHook* h) { hook = h; } + void check(); operator bool() { return (value != NULL); } static void reset_all(); diff --git a/src/modules.cpp b/src/modules.cpp index 6510c9423..55d41674b 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -655,7 +655,7 @@ ServiceProvider* ModuleManager::FindService(ServiceType type, const std::string& } dynamic_reference_base::dynamic_reference_base(Module* Creator, const std::string& Name) - : name(Name), value(NULL), creator(Creator) + : name(Name), hook(NULL), value(NULL), creator(Creator) { if (!dynrefs) dynrefs = new insp::intrusive_list; @@ -688,7 +688,15 @@ void dynamic_reference_base::resolve() // to ensure a dynref with the same name as another one resolves to the same object std::multimap::iterator i = ServerInstance->Modules.DataProviders.lower_bound(name); if ((i != ServerInstance->Modules.DataProviders.end()) && (i->first == this->name)) - value = static_cast(i->second); + { + ServiceProvider* newvalue = i->second; + if (value != newvalue) + { + value = newvalue; + if (hook) + hook->OnCapture(); + } + } else value = NULL; } -- cgit v1.2.3 From 0204f2254dd44db8b68fd0e658fda130e84aa9cf Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Wed, 11 Feb 2015 17:24:14 +0100 Subject: Remove class Event and the OnEvent hook --- include/modules.h | 36 +----------------------------------- src/modules.cpp | 8 -------- 2 files changed, 1 insertion(+), 43 deletions(-) (limited to 'src/modules.cpp') diff --git a/include/modules.h b/include/modules.h index 5a4090dfb..d034ebac2 100644 --- a/include/modules.h +++ b/include/modules.h @@ -206,34 +206,6 @@ class CoreExport Version virtual ~Version() {} }; -/** The Event class is a unicast message directed at all modules. - * When the class is properly instantiated it may be sent to all modules - * using the Send() method, which will trigger the OnEvent method in - * all modules passing the object as its parameter. - */ -class CoreExport Event : public classbase -{ - public: - /** This is a pointer to the sender of the message, which can be used to - * directly trigger events, or to create a reply. - */ - ModuleRef source; - /** The event identifier. - * This is arbitary text which should be used to distinguish - * one type of event from another. - */ - const std::string id; - - /** Create a new Event - */ - Event(Module* src, const std::string &eventid); - /** Send the Event. - * The return result of an Event::Send() will always be NULL as - * no replies are expected. - */ - void Send(); -}; - class CoreExport DataProvider : public ServiceProvider { public: @@ -260,7 +232,7 @@ enum Implementation I_OnUnloadModule, I_OnBackgroundTimer, I_OnPreCommand, I_OnCheckReady, I_OnCheckInvite, I_OnRawMode, I_OnCheckKey, I_OnCheckLimit, I_OnCheckBan, I_OnCheckChannelBan, I_OnExtBanCheck, I_OnStats, I_OnChangeLocalUserHost, I_OnPreTopicChange, - I_OnPostTopicChange, I_OnEvent, I_OnPostConnect, + I_OnPostTopicChange, I_OnPostConnect, I_OnChangeLocalUserGECOS, I_OnUserRegister, I_OnChannelPreDelete, I_OnChannelDelete, I_OnPostOper, I_OnSyncNetwork, I_OnSetAway, I_OnPostCommand, I_OnPostJoin, I_OnWhoisLine, I_OnBuildNeighborList, I_OnGarbageCollect, I_OnSetConnectClass, @@ -952,12 +924,6 @@ class CoreExport Module : public classbase, public usecountbase */ virtual void OnPostTopicChange(User* user, Channel* chan, const std::string &topic); - /** Called whenever an Event class is sent to all modules by another module. - * You should *always* check the value of Event::id to determine the event type. - * @param event The Event class being received - */ - virtual void OnEvent(Event& event); - /** Called whenever a password check is to be made. Replaces the old OldOperCompare API. * The password field (from the config file) is in 'password' and is to be compared against * 'input'. This method allows for encryption of passwords (oper, connect:allow, die/restart, etc). diff --git a/src/modules.cpp b/src/modules.cpp index 55d41674b..1c33785b0 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -52,13 +52,6 @@ Version::Version(const std::string &desc, int flags, const std::string& linkdata { } -Event::Event(Module* src, const std::string &eventid) : source(src), id(eventid) { } - -void Event::Send() -{ - FOREACH_MOD(OnEvent, (*this)); -} - // These declarations define the behavours of the base class Module (which does nothing at all) Module::Module() { } @@ -119,7 +112,6 @@ ModResult Module::OnStats(char, User*, string_list&) { DetachEvent(I_OnStats); r ModResult Module::OnChangeLocalUserHost(LocalUser*, const std::string&) { DetachEvent(I_OnChangeLocalUserHost); return MOD_RES_PASSTHRU; } ModResult Module::OnChangeLocalUserGECOS(LocalUser*, const std::string&) { DetachEvent(I_OnChangeLocalUserGECOS); return MOD_RES_PASSTHRU; } ModResult Module::OnPreTopicChange(User*, Channel*, const std::string&) { DetachEvent(I_OnPreTopicChange); return MOD_RES_PASSTHRU; } -void Module::OnEvent(Event&) { DetachEvent(I_OnEvent); } ModResult Module::OnPassCompare(Extensible* ex, const std::string &password, const std::string &input, const std::string& hashtype) { DetachEvent(I_OnPassCompare); return MOD_RES_PASSTHRU; } void Module::OnPostConnect(User*) { DetachEvent(I_OnPostConnect); } void Module::OnUserMessage(User*, void*, int, const std::string&, char, const CUList&, MessageType) { DetachEvent(I_OnUserMessage); } -- cgit v1.2.3