summaryrefslogtreecommitdiff
path: root/src/modules/extra
diff options
context:
space:
mode:
authorpeavey <peavey@e03df62e-2008-0410-955e-edbf42e46eb7>2006-12-30 21:59:22 +0000
committerpeavey <peavey@e03df62e-2008-0410-955e-edbf42e46eb7>2006-12-30 21:59:22 +0000
commitf82ad6d984af57b7dc6806a0ee2555d3187cb200 (patch)
tree7050e6895ace0eeb33929106bafcf57cbe22b875 /src/modules/extra
parenta4743b222b5fa099434ecfe78921fc77e267c907 (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.cpp120
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: