From 3a7023f2c595d14778b3f1f7e53d3914698dd500 Mon Sep 17 00:00:00 2001 From: om Date: Thu, 20 Jul 2006 17:47:15 +0000 Subject: Updates, should be able to safely unload client modules with queries in progress now... Ideas on how to test this welcome ;p git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@4464 e03df62e-2008-0410-955e-edbf42e46eb7 --- src/modules/extra/m_pgsql.cpp | 56 ++++++++++++++++++++++++++++++++++++++++--- src/modules/extra/m_sqlv2.h | 7 +++++- 2 files changed, 59 insertions(+), 4 deletions(-) (limited to 'src/modules') diff --git a/src/modules/extra/m_pgsql.cpp b/src/modules/extra/m_pgsql.cpp index e36821cb9..c67ca0854 100644 --- a/src/modules/extra/m_pgsql.cpp +++ b/src/modules/extra/m_pgsql.cpp @@ -87,8 +87,10 @@ enum SQLstatus { CREAD, CWRITE, WREAD, WWRITE }; class QueryQueue : public classbase { private: - std::deque priority; /* The priority queue */ - std::deque normal; /* The 'normal' queue */ + typedef std::deque ReqDeque; + + ReqDeque priority; /* The priority queue */ + ReqDeque normal; /* The 'normal' queue */ enum { PRI, NOR, NON } which; /* Which queue the currently active element is at the front of */ public: @@ -163,6 +165,33 @@ public: { return priority.size() + normal.size(); } + + void PurgeModule(Module* mod) + { + DoPurgeModule(mod, priority); + DoPurgeModule(mod, normal); + } + +private: + void DoPurgeModule(Module* mod, ReqDeque& q) + { + for(ReqDeque::iterator iter = q.begin(); iter != q.end(); iter++) + { + if(iter->GetSource() == mod) + { + if(iter->id == front().id) + { + /* It's the currently active query.. :x */ + iter->SetSource(NULL); + } + else + { + /* It hasn't been executed yet..just remove it */ + iter = q.erase(iter); + } + } + } + } }; /** PgSQLresult is a subclass of the mostly-pure-virtual class SQLresult. @@ -405,6 +434,8 @@ public: SQLerror DoQuery(const SQLrequest &req); SQLerror Query(const SQLrequest &req); + + void OnUnloadModule(Module* mod); }; class ModulePgSQL : public Module @@ -431,7 +462,7 @@ public: void Implements(char* List) { - List[I_OnRequest] = List[I_OnRehash] = List[I_OnUserRegister] = List[I_OnCheckReady] = List[I_OnUserDisconnect] = 1; + List[I_OnUnloadModule] = List[I_OnRequest] = List[I_OnRehash] = List[I_OnUserRegister] = List[I_OnCheckReady] = List[I_OnUserDisconnect] = 1; } virtual void OnRehash(const std::string ¶meter) @@ -497,6 +528,20 @@ public: return NULL; } + virtual void OnUnloadModule(Module* mod, const std::string& name) + { + /* When a module unloads we have to check all the pending queries for all our connections + * and set the Module* specifying where the query came from to NULL. If the query has already + * been dispatched then when it is processed it will be dropped if the pointer is NULL. + * + * If the queries we find are not already being executed then we can simply remove them immediately. + */ + for(ConnMap::iterator iter = connections.begin(); iter != connections.end(); iter++) + { + + } + } + unsigned long NewID() { if (currid+1 == 0) @@ -930,6 +975,11 @@ SQLerror SQLConn::Query(const SQLrequest &req) } } +void SQLConn::OnUnloadModule(Module* mod) +{ + queue.PurgeModule(mod); +} + class ModulePgSQLFactory : public ModuleFactory { public: diff --git a/src/modules/extra/m_sqlv2.h b/src/modules/extra/m_sqlv2.h index d93e59b47..0a14124bc 100644 --- a/src/modules/extra/m_sqlv2.h +++ b/src/modules/extra/m_sqlv2.h @@ -81,7 +81,12 @@ public: SQLrequest(Module* s, Module* d, const std::string &q, const std::string &id, bool p = false) : Request(SQLREQID, s, d), query(q), dbid(id), pri(p), id(0) { - } + } + + void SetSource(Module* mod) + { + source = mod; + } }; class SQLfield -- cgit v1.2.3