summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2011-01-08 18:55:12 -0500
committerAdam <Adam@anope.org>2011-01-08 18:55:12 -0500
commitce8a069eb57e20b62170faf1127228724ff2cdf0 (patch)
tree88bd2f0f6575412646ef4fd4b662721782949f3f
parent2ba97aee6c7b02e9ec62b4ae28fc041423936e10 (diff)
Changed db_mysql_live to use a safer mutex system to prevent deadlocks
-rw-r--r--include/account.h2
-rw-r--r--modules/extra/db_mysql_live.cpp33
2 files changed, 25 insertions, 10 deletions
diff --git a/include/account.h b/include/account.h
index afef1236d..1a0c5a751 100644
--- a/include/account.h
+++ b/include/account.h
@@ -42,7 +42,7 @@ enum NickNameFlag
};
const Anope::string NickNameFlagStrings[] = {
- "NS_BEGIN", "NS_FORBIDDEN", "NS_NO_EXPIRE", "NS_HELD", "NS_COLLIDED", "NS_END", ""
+ "NS_BEGIN", "NS_FORBIDDEN", "NS_NO_EXPIRE", "NS_HELD", "NS_COLLIDED", ""
};
/** Flags set on NickCores
diff --git a/modules/extra/db_mysql_live.cpp b/modules/extra/db_mysql_live.cpp
index ebf6a67c9..f110b631d 100644
--- a/modules/extra/db_mysql_live.cpp
+++ b/modules/extra/db_mysql_live.cpp
@@ -3,17 +3,24 @@
class CommandMutex;
static std::list<CommandMutex *> commands;
+
+/* Current command being processed by the core */
static CommandMutex *current_command = NULL;
+/* Mutex held by the core when it is processing. Used by threads to halt the core */
+static Mutex main_mutex;
class CommandMutex : public Thread
{
public:
+ // Mutex used by this command to allow the core to drop and pick up processing of it at will
Mutex mutex;
+ // Set to true when this thread is processing data that is not thread safe (eg, the command)
+ bool processing;
Command *command;
CommandSource source;
std::vector<Anope::string> params;
- CommandMutex() : Thread()
+ CommandMutex() : Thread(), processing(true)
{
commands.push_back(this);
current_command = this;
@@ -48,7 +55,7 @@ class CommandMutex : public Thread
}
}
- this->mutex.Unlock();
+ main_mutex.Unlock();
}
};
@@ -91,7 +98,7 @@ class MySQLLiveModule : public Module, public Pipe
// Give processing to the command thread
Log(LOG_DEBUG_2) << "db_mysql_live: Waiting for command thread " << cm->command->name << " from " << source.u->nick;
threadEngine.Start(cm);
- cm->mutex.Lock();
+ main_mutex.Lock();
}
catch (const CoreException &ex)
{
@@ -111,7 +118,7 @@ class MySQLLiveModule : public Module, public Pipe
CommandMutex *cm = *it;
// Thread engine will pick this up later
- if (cm->GetExitState())
+ if (cm->GetExitState() || !cm->processing)
continue;
Log(LOG_DEBUG_2) << "db_mysql_live: Waiting for command thread " << cm->command->name << " from " << cm->source.u->nick;
@@ -120,7 +127,7 @@ class MySQLLiveModule : public Module, public Pipe
// Unlock to give processing back to the command thread
cm->mutex.Unlock();
// Relock to regain processing once the command thread hangs for any reason
- cm->mutex.Lock();
+ main_mutex.Lock();
current_command = NULL;
}
@@ -135,9 +142,11 @@ class MySQLLiveModule : public Module, public Pipe
CommandMutex *cm = current_command;
// Give it back to the core
- cm->mutex.Unlock();
+ cm->processing = false;
+ main_mutex.Unlock();
SQLResult res = this->RunQuery("SELECT * FROM `anope_bs_core` WHERE `nick` = '" + this->Escape(nick) + "'");
// And take it back...
+ cm->processing = true;
this->Notify();
cm->mutex.Lock();
@@ -170,8 +179,10 @@ class MySQLLiveModule : public Module, public Pipe
CommandMutex *cm = current_command;
- cm->mutex.Unlock();
+ cm->processing = false;
+ main_mutex.Unlock();
SQLResult res = this->RunQuery("SELECT * FROM `anope_cs_info` WHERE `name` = '" + this->Escape(chname) + "'");
+ cm->processing = true;
this->Notify();
cm->mutex.Lock();
@@ -254,8 +265,10 @@ class MySQLLiveModule : public Module, public Pipe
CommandMutex *cm = current_command;
- cm->mutex.Unlock();
+ cm->processing = false;
+ main_mutex.Unlock();
SQLResult res = this->RunQuery("SELECT * FROM `anope_ns_alias` WHERE `nick` = '" + this->Escape(nick) + "'");
+ cm->processing = true;
this->Notify();
cm->mutex.Lock();
@@ -299,8 +312,10 @@ class MySQLLiveModule : public Module, public Pipe
CommandMutex *cm = current_command;
- cm->mutex.Unlock();
+ cm->processing = false;
+ main_mutex.Unlock();
SQLResult res = this->RunQuery("SELECT * FROM `anope_ns_core` WHERE `name` = '" + this->Escape(nick) + "'");
+ cm->processing = true;
this->Notify();
cm->mutex.Lock();