diff options
author | peavey <peavey@e03df62e-2008-0410-955e-edbf42e46eb7> | 2006-12-30 21:59:22 +0000 |
---|---|---|
committer | peavey <peavey@e03df62e-2008-0410-955e-edbf42e46eb7> | 2006-12-30 21:59:22 +0000 |
commit | f82ad6d984af57b7dc6806a0ee2555d3187cb200 (patch) | |
tree | 7050e6895ace0eeb33929106bafcf57cbe22b875 /src/modules/extra | |
parent | a4743b222b5fa099434ecfe78921fc77e267c907 (diff) |
Make it safe to lose connection to sql server.
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@6183 e03df62e-2008-0410-955e-edbf42e46eb7
Diffstat (limited to 'src/modules/extra')
-rw-r--r-- | src/modules/extra/m_pgsql.cpp | 120 |
1 files changed, 84 insertions, 36 deletions
diff --git a/src/modules/extra/m_pgsql.cpp b/src/modules/extra/m_pgsql.cpp index 21c57bce1..96ffa3a96 100644 --- a/src/modules/extra/m_pgsql.cpp +++ b/src/modules/extra/m_pgsql.cpp @@ -476,33 +476,35 @@ public: bool DoConnect(); virtual void Close(); - + + void DoClose(); + bool DoPoll(); - + bool DoConnectedPoll(); bool DoResetPoll(); - + void ShowStatus(); - + virtual bool OnDataReady(); virtual bool OnWriteReady(); - + virtual bool OnConnected(); - + bool DoEvent(); - + bool Reconnect(); - + std::string MkInfoStr(); - + const char* StatusStr(); - + SQLerror DoQuery(SQLrequest &req); - + SQLerror Query(const SQLrequest &req); - + void OnUnloadModule(Module* mod); const SQLhost GetConfHost(); @@ -534,7 +536,7 @@ SQLConn::SQLConn(InspIRCd* SI, Module* self, const SQLhost& hi, const SQLhost& c SQLConn::~SQLConn() { - Close(); + DoClose(); } bool SQLConn::DoConnect() @@ -544,14 +546,14 @@ bool SQLConn::DoConnect() if(!(sql = PQconnectStart(MkInfoStr().c_str()))) { Instance->Log(DEBUG, "Couldn't allocate PGconn structure, aborting: %s", PQerrorMessage(sql)); - Close(); + DoClose(); return false; } if(PQstatus(sql) == CONNECTION_BAD) { Instance->Log(DEBUG, "PQconnectStart failed: %s", PQerrorMessage(sql)); - Close(); + DoClose(); return false; } @@ -560,7 +562,7 @@ bool SQLConn::DoConnect() if(PQsetnonblocking(sql, 1) == -1) { Instance->Log(DEBUG, "Couldn't set connection nonblocking: %s", PQerrorMessage(sql)); - Close(); + DoClose(); return false; } @@ -575,7 +577,7 @@ bool SQLConn::DoConnect() if(this->fd <= -1) { Instance->Log(DEBUG, "PQsocket says we have an invalid FD: %d", this->fd); - Close(); + DoClose(); return false; } @@ -583,7 +585,7 @@ bool SQLConn::DoConnect() if (!this->Instance->SE->AddFd(this)) { Instance->Log(DEBUG, "A PQsocket cant be added to the socket engine!"); - Close(); + DoClose(); return false; } @@ -592,24 +594,8 @@ bool SQLConn::DoConnect() return DoPoll(); } -void SQLConn::Close() -{ - Instance->Log(DEBUG,"SQLConn::Close"); - - if (!this->Instance->SE->DelFd(this)) - { - Instance->Log(DEBUG, "PQsocket cant be removed from the socket engine!"); - } - this->fd = -1; - this->state = I_ERROR; - this->OnError(I_ERR_SOCKET); - this->ClosePending = true; - - if(sql) - { - PQfinish(sql); - sql = NULL; - } +void SQLConn::Close() { + DoClose(); } bool SQLConn::DoPoll() @@ -1055,6 +1041,7 @@ class ModulePgSQL : public Module private: ConnMap connections; + ConnMap deadconnections; unsigned long currid; char* sqlsuccess; @@ -1099,6 +1086,7 @@ public: bool HasHost(const SQLhost &host) { + ClearDeadConnections(); for (ConnMap::iterator iter = connections.begin(); iter != connections.end(); iter++) { if (host == iter->second->GetConfHost()) @@ -1109,6 +1097,7 @@ public: bool HostInConf(const SQLhost &h) { + ClearDeadConnections(); ConfigReader conf(ServerInstance); for(int i = 0; i < conf.Enumerate("database"); i++) { @@ -1128,6 +1117,7 @@ public: void ReadConf() { + ClearDeadConnections(); ConfigReader conf(ServerInstance); for(int i = 0; i < conf.Enumerate("database"); i++) @@ -1182,6 +1172,7 @@ public: void ClearOldConnections() { + ClearDeadConnections(); ConnMap::iterator iter,safei; for (iter = connections.begin(); iter != connections.end(); iter++) { @@ -1197,6 +1188,7 @@ public: void ClearAllConnections() { + ClearDeadConnections(); ConnMap::iterator iter; while ((iter = connections.begin()) != connections.end()) { @@ -1205,6 +1197,39 @@ public: } } + void ClearDeadConnections() + { +/* + ConnMap::iterator iter,safei; + for (iter = connections.begin(); iter != connections.end(); iter++) + { + if (sizeof(iter->second) <= 0) + { + safei = iter; + --iter; + connections.erase(safei); + } + ServerInstance->Log(DEBUG, "<*********> sizeof(iter->second): %d", sizeof(iter->second)); + } +*/ + ConnMap::iterator di; + while ((di = deadconnections.begin()) != deadconnections.end()) + { + ConnMap::iterator iter = connections.find(di->first); + if (iter != connections.end()) + { + connections.erase(iter); + ServerInstance->Log(DEBUG, "<*********> sizeof(iter->second): %d", sizeof(iter->second)); + } + deadconnections.erase(di); + } + } + + void AddDeadConn(std::string id, SQLConn* conn) + { + deadconnections[id] = conn; + } + void AddConn(const SQLhost& hi, const SQLhost& ci) { if (HasHost(ci)) @@ -1288,6 +1313,29 @@ void SQLresolver::OnLookupComplete(const std::string &result) ((ModulePgSQL*)mod)->ClearOldConnections(); } +/* move this here too, to use AddDeadConn */ +void SQLConn::DoClose() +{ + Instance->Log(DEBUG,"SQLConn::Close"); + + if (!this->Instance->SE->DelFd(this)) + { + Instance->Log(DEBUG, "PQsocket cant be removed from the socket engine!"); + } + this->fd = -1; + this->state = I_ERROR; + this->OnError(I_ERR_SOCKET); + this->ClosePending = true; + + if(sql) + { + PQfinish(sql); + sql = NULL; + } + + ((ModulePgSQL*)us)->AddDeadConn(confhost.id, this); +} + class ModulePgSQLFactory : public ModuleFactory { public: |