diff options
author | Adam <Adam@anope.org> | 2011-02-20 01:05:16 -0500 |
---|---|---|
committer | Adam <Adam@anope.org> | 2011-02-20 01:05:16 -0500 |
commit | c83b2b73d7c5f264dedb67b878d116b5b10a4742 (patch) | |
tree | 407251a2bb3bf738194b6ec7654b0872b6bab1d5 | |
parent | dfbb5264fac5b418da536cc968aed4bf5cde8b76 (diff) |
Much more work on the live SQL. Should work pretty decently now under heavy load.
-rw-r--r-- | include/CMakeLists.txt | 5 | ||||
-rw-r--r-- | include/bots.h | 2 | ||||
-rw-r--r-- | include/commands.h | 6 | ||||
-rw-r--r-- | include/modules.h | 7 | ||||
-rw-r--r-- | modules/extra/async_commands.h | 4 | ||||
-rw-r--r-- | modules/extra/db_mysql_live.cpp | 355 | ||||
-rw-r--r-- | modules/extra/m_async_commands.cpp | 95 | ||||
-rw-r--r-- | modules/extra/m_mysql.cpp | 17 | ||||
-rw-r--r-- | src/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/base.cpp | 3 | ||||
-rw-r--r-- | src/bots.cpp | 4 | ||||
-rw-r--r-- | src/command.cpp | 40 | ||||
-rw-r--r-- | src/commands.cpp | 2 | ||||
-rw-r--r-- | src/modulemanager.cpp | 2 | ||||
-rw-r--r-- | src/threadengines/threadengine_pthread.cpp | 1 | ||||
-rw-r--r-- | src/threadengines/threadengine_win32.cpp | 1 |
16 files changed, 406 insertions, 141 deletions
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 8b292aea2..a2f8c42d7 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -19,6 +19,8 @@ endif(NOT WIN32) set(PCH_SOURCES_GCH "") if(CMAKE_COMPILER_IS_GNUCXX) string(REPLACE " " ";" PCH_CXXFLAGS ${CXXFLAGS}) + file(GLOB INCLUDE_SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.h") + remove_item_from_list(INCLUDE_SRCS "version.h") set(PCH_SOURCES "module.h;modules.h;services.h") foreach(PCH_SOURCE ${PCH_SOURCES}) @@ -32,7 +34,8 @@ if(CMAKE_COMPILER_IS_GNUCXX) set(PCH_SOURCES_GCH "${PCH_SOURCES_GCH};${CMAKE_CURRENT_BINARY_DIR}/${PCH_SOURCE}.gch") add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PCH_SOURCE}.gch - COMMAND ${CMAKE_CXX_COMPILER} ARGS ${PCH_CXXFLAGS} ${PCH_EXTRAFLAGS} -I${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/${PCH_SOURCE} -o ${CMAKE_CURRENT_BINARY_DIR}/${PCH_SOURCE}.gch VERBATIM + COMMAND ${CMAKE_CXX_COMPILER} ARGS ${PCH_CXXFLAGS} ${PCH_EXTRAFLAGS} -I${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/${PCH_SOURCE} -o ${CMAKE_CURRENT_BINARY_DIR}/${PCH_SOURCE}.gch + DEPENDS ${INCLUDE_SRCS} VERBATIM ) endforeach(PCH_SOURCE ${PCH_SOURCES}) endif(CMAKE_COMPILER_IS_GNUCXX) diff --git a/include/bots.h b/include/bots.h index 84c4fa2ec..7cdf417f1 100644 --- a/include/bots.h +++ b/include/bots.h @@ -51,6 +51,8 @@ class CoreExport BotInfo : public User, public Flags<BotFlag, BI_END> */ virtual ~BotInfo(); + void SetIdent(const Anope::string &sident); + /** Change the nickname for the bot. * @param newnick The nick to change to */ diff --git a/include/commands.h b/include/commands.h index a2d6643fe..8320c531a 100644 --- a/include/commands.h +++ b/include/commands.h @@ -69,15 +69,15 @@ struct CoreExport CommandSource std::list<Anope::string> reply; - ~CommandSource(); - void Reply(const char *message, ...); void Reply(const Anope::string &message); + + void DoReply(); }; /** Every services command is a class, inheriting from Command. */ -class CoreExport Command : public Flags<CommandFlag> +class CoreExport Command : public Flags<CommandFlag>, public Base { Anope::string desc; diff --git a/include/modules.h b/include/modules.h index 4532549f1..c407e2c21 100644 --- a/include/modules.h +++ b/include/modules.h @@ -1066,6 +1066,11 @@ class CoreExport Module : public Extensible * @return MOD_STOP to stop processing completely */ virtual EventReturn OnPrivmsg(User *u, ChannelInfo *ci, Anope::string &msg, bool &Allow) { return EVENT_CONTINUE; } + + /** Called when any object is destroyed + * @param b The object + */ + virtual void OnObjectDestroy(Base *b) { } }; /** Implementation-specific flags which may be set in ModuleManager::Attach() @@ -1118,7 +1123,7 @@ enum Implementation I_OnServerQuit, I_OnTopicUpdated, I_OnEncrypt, I_OnEncryptCheckLen, I_OnDecrypt, I_OnCheckPassword, I_OnChannelModeSet, I_OnChannelModeUnset, I_OnUserModeSet, I_OnUserModeUnset, I_OnChannelModeAdd, I_OnUserModeAdd, - I_OnMLock, I_OnUnMLock, I_OnServerSync, I_OnUplinkSync, I_OnBotPrivmsg, I_OnPrivmsg, + I_OnMLock, I_OnUnMLock, I_OnServerSync, I_OnUplinkSync, I_OnBotPrivmsg, I_OnPrivmsg, I_OnObjectDestroy, I_END }; diff --git a/modules/extra/async_commands.h b/modules/extra/async_commands.h index b6b9e7c2b..a2f650bae 100644 --- a/modules/extra/async_commands.h +++ b/modules/extra/async_commands.h @@ -6,11 +6,11 @@ class CommandMutex : public Thread 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; + Command *command; std::vector<Anope::string> params; - CommandMutex() : Thread(), processing(true) { } + CommandMutex(CommandSource &s, Command *c, const std::vector<Anope::string> &p) : Thread(), processing(true), source(s), command(c), params(p) { } ~CommandMutex() { } diff --git a/modules/extra/db_mysql_live.cpp b/modules/extra/db_mysql_live.cpp index 8f14f3998..c5e645be6 100644 --- a/modules/extra/db_mysql_live.cpp +++ b/modules/extra/db_mysql_live.cpp @@ -2,59 +2,51 @@ #include "async_commands.h" #include "sql.h" -class MySQLLiveModule : public Module +class SQLCache : public Timer { - service_reference<SQLProvider> SQL; - service_reference<AsynchCommandsService> ACS; + typedef std::map<Anope::string, time_t, std::less<ci::string> > cache_map; + cache_map cache; + public: - SQLResult RunQuery(const Anope::string &query) + SQLCache() : Timer(300, Anope::CurTime, true) { } + + bool Check(const Anope::string &item) { - if (!this->SQL) - throw SQLException("Unable to locate SQL reference, is m_mysql loaded and configured correctly?"); + cache_map::iterator it = this->cache.find(item); + if (it != this->cache.end() && Anope::CurTime - it->second < 5) + return true; - return SQL->RunQuery(query); + this->cache[item] = Anope::CurTime; + return false; } - const Anope::string Escape(const Anope::string &query) + void Tick(time_t) { - return SQL ? SQL->Escape(query) : query; - } + for (cache_map::iterator it = this->cache.begin(), next_it; it != this->cache.end(); it = next_it) + { + next_it = it; + ++next_it; - CommandMutex *CurrentCommand() - { - if (this->ACS) - return this->ACS->CurrentCommand(); - return NULL; + if (Anope::CurTime - it->second > 5) + this->cache.erase(it); + } } +}; +class BotInfoUpdater : public SQLInterface, public SQLCache +{ public: - MySQLLiveModule(const Anope::string &modname, const Anope::string &creator) : - Module(modname, creator), SQL("mysql/main"), ACS("asynch_commands") + BotInfoUpdater(Module *m) : SQLInterface(m) { } + + void OnResult(const SQLResult &r) { - Implementation i[] = { I_OnFindBot, I_OnFindChan, I_OnFindNick, I_OnFindCore }; - ModuleManager::Attach(i, this, 4); + BotInfoUpdater::Process(r); } - void OnFindBot(const Anope::string &nick) + static void Process(const SQLResult &res) { - static bool lookup = true; - if (lookup == false) - { - lookup = true; - return; - } - try { - CommandMutex *current_command = this->CurrentCommand(); - - if (current_command) - current_command->Unlock(); - SQLResult res = this->RunQuery("SELECT * FROM `anope_bs_core` WHERE `nick` = '" + this->Escape(nick) + "'"); - if (current_command) - current_command->Lock(); - - lookup = false; BotInfo *bi = findbot(res.Get(0, "nick")); if (!bi) bi = new BotInfo(res.Get(0, "nick"), res.Get(0, "user"), res.Get(0, "host"), res.Get(0, "rname")); @@ -70,30 +62,28 @@ class MySQLLiveModule : public Module bi->created = convertTo<time_t>(res.Get(0, "created")); bi->chancount = convertTo<uint32>(res.Get(0, "chancount")); } - catch (const SQLException &) { } + catch (const SQLException &ex) + { + Log(LOG_DEBUG) << ex.GetReason(); + } catch (const ConvertException &) { } } +}; - void OnFindChan(const Anope::string &chname) +class ChanInfoUpdater : public SQLInterface, public SQLCache +{ + public: + ChanInfoUpdater(Module *m) : SQLInterface(m) { } + + void OnResult(const SQLResult &r) { - static bool lookup = true; - if (lookup == false) - { - lookup = true; - return; - } + ChanInfoUpdater::Process(r); + } + static void Process(const SQLResult &res) + { try { - CommandMutex *current_command = this->CurrentCommand(); - - if (current_command) - current_command->Unlock(); - SQLResult res = this->RunQuery("SELECT * FROM `anope_cs_info` WHERE `name` = '" + this->Escape(chname) + "'"); - if (current_command) - current_command->Lock(); - - lookup = false; ChannelInfo *ci = cs_findchan(res.Get(0, "name")); if (!ci) ci = new ChannelInfo(res.Get(0, "name")); @@ -159,33 +149,31 @@ class MySQLLiveModule : public Module if (ci->c) check_modes(ci->c); } - catch (const SQLException &) { } + catch (const SQLException &ex) + { + Log(LOG_DEBUG) << ex.GetReason(); + } catch (const ConvertException &) { } } +}; - void OnFindNick(const Anope::string &nick) +class NickInfoUpdater : public SQLInterface, public SQLCache +{ + public: + NickInfoUpdater(Module *m) : SQLInterface(m) { } + + void OnResult(const SQLResult &r) { - static bool lookup = true; - if (lookup == false) - { - lookup = true; - return; - } + NickInfoUpdater::Process(r); + } + static void Process(const SQLResult &res) + { try { - CommandMutex *current_command = this->CurrentCommand(); - - if (current_command) - current_command->Unlock(); - SQLResult res = this->RunQuery("SELECT * FROM `anope_ns_alias` WHERE `nick` = '" + this->Escape(nick) + "'"); - if (current_command) - current_command->Lock(); - NickCore *nc = findcore(res.Get(0, "display")); if (!nc) return; - lookup = false; NickAlias *na = findnick(res.Get(0, "nick")); if (!na) na = new NickAlias(res.Get(0, "nick"), nc); @@ -208,30 +196,28 @@ class MySQLLiveModule : public Module na->nc->aliases.push_back(na); } } - catch (const SQLException &) { } + catch (const SQLException &ex) + { + Log(LOG_DEBUG) << ex.GetReason(); + } catch (const ConvertException &) { } } +}; - void OnFindCore(const Anope::string &nick) +class NickCoreUpdater : public SQLInterface, public SQLCache +{ + public: + NickCoreUpdater(Module *m) : SQLInterface(m) { } + + void OnResult(const SQLResult &r) { - static bool lookup = true; - if (lookup == false) - { - lookup = true; - return; - } + NickCoreUpdater::Process(r); + } + static void Process(const SQLResult &res) + { try { - CommandMutex *current_command = this->CurrentCommand(); - - if (current_command) - current_command->Unlock(); - SQLResult res = this->RunQuery("SELECT * FROM `anope_ns_core` WHERE `name` = '" + this->Escape(nick) + "'"); - if (current_command) - current_command->Lock(); - - lookup = false; NickCore *nc = findcore(res.Get(0, "display")); if (!nc) nc = new NickCore(res.Get(0, "display")); @@ -243,9 +229,202 @@ class MySQLLiveModule : public Module nc->FromString(BuildStringVector(res.Get(0, "flags"))); nc->language = res.Get(0, "language"); } - catch (const SQLException &) { } + catch (const SQLException &ex) + { + Log(LOG_DEBUG) << ex.GetReason(); + } catch (const ConvertException &) { } } }; +class MySQLLiveModule : public Module +{ + service_reference<SQLProvider> SQL; + service_reference<AsynchCommandsService> ACS; + + BotInfoUpdater botinfoupdater; + ChanInfoUpdater chaninfoupdater; + NickInfoUpdater nickinfoupdater; + NickCoreUpdater nickcoreupdater; + + SQLResult RunQuery(const Anope::string &query) + { + if (!this->SQL) + throw SQLException("Unable to locate SQL reference, is m_mysql loaded and configured correctly?"); + + SQLResult res = SQL->RunQuery(query); + if (!res.GetError().empty()) + throw SQLException(res.GetError()); + return res; + } + + void RunQuery(SQLInterface *i, const Anope::string &query) + { + if (!this->SQL) + throw SQLException("Unable to locate SQL reference, is m_mysql loaded and configured correctly?"); + + return SQL->Run(i, query); + } + + const Anope::string Escape(const Anope::string &query) + { + return SQL ? SQL->Escape(query) : query; + } + + CommandMutex *CurrentCommand() + { + if (this->ACS) + return this->ACS->CurrentCommand(); + return NULL; + } + + public: + MySQLLiveModule(const Anope::string &modname, const Anope::string &creator) : + Module(modname, creator), SQL("mysql/main"), ACS("asynch_commands"), botinfoupdater(this), + chaninfoupdater(this), nickinfoupdater(this), nickcoreupdater(this) + { + Implementation i[] = { I_OnFindBot, I_OnFindChan, I_OnFindNick, I_OnFindCore, I_OnPreShutdown }; + ModuleManager::Attach(i, this, 5); + } + + void OnPreShutdown() + { + Implementation i[] = { I_OnFindBot, I_OnFindChan, I_OnFindNick, I_OnFindCore }; + for (size_t j = 0; j < 4; ++j) + ModuleManager::Detach(i[j], this); + } + + void OnFindBot(const Anope::string &nick) + { + if (botinfoupdater.Check(nick)) + return; + + try + { + Anope::string query = "SELECT * FROM `anope_bs_core` WHERE `nick` = '" + this->Escape(nick) + "'"; + CommandMutex *current_command = this->CurrentCommand(); + if (current_command) + { + current_command->Unlock(); + try + { + SQLResult res = this->RunQuery(query); + current_command->Lock(); + BotInfoUpdater::Process(res); + } + catch (const SQLException &ex) + { + current_command->Lock(); + throw; + } + } + else + this->RunQuery(&botinfoupdater, query); + } + catch (const SQLException &ex) + { + Log(LOG_DEBUG) << "OnBotChan: " << ex.GetReason(); + } + } + + void OnFindChan(const Anope::string &chname) + { + if (chaninfoupdater.Check(chname)) + return; + + try + { + Anope::string query = "SELECT * FROM `anope_cs_info` WHERE `name` = '" + this->Escape(chname) + "'"; + CommandMutex *current_command = this->CurrentCommand(); + if (current_command) + { + current_command->Unlock(); + try + { + SQLResult res = this->RunQuery(query); + current_command->Lock(); + ChanInfoUpdater::Process(res); + } + catch (const SQLException &) + { + current_command->Lock(); + throw; + } + } + else + this->RunQuery(&chaninfoupdater, query); + } + catch (const SQLException &ex) + { + Log(LOG_DEBUG) << "OnFindChan: " << ex.GetReason(); + } + } + + void OnFindNick(const Anope::string &nick) + { + if (nickinfoupdater.Check(nick)) + return; + + try + { + Anope::string query = "SELECT * FROM `anope_ns_alias` WHERE `nick` = '" + this->Escape(nick) + "'"; + CommandMutex *current_command = this->CurrentCommand(); + if (current_command) + { + current_command->Unlock(); + try + { + SQLResult res = this->RunQuery(query); + current_command->Lock(); + NickInfoUpdater::Process(res); + } + catch (const SQLException &) + { + current_command->Lock(); + throw; + } + } + else + this->RunQuery(&nickinfoupdater, query); + } + catch (const SQLException &ex) + { + Log(LOG_DEBUG) << "OnFindNick: " << ex.GetReason(); + } + } + + void OnFindCore(const Anope::string &nick) + { + if (nickcoreupdater.Check(nick)) + return; + + try + { + Anope::string query = "SELECT * FROM `anope_ns_core` WHERE `display` = '" + this->Escape(nick) + "'"; + CommandMutex *current_command = this->CurrentCommand(); + if (current_command) + { + current_command->Unlock(); + try + { + SQLResult res = this->RunQuery(query); + current_command->Lock(); + NickCoreUpdater::Process(res); + } + catch (const SQLException &) + { + current_command->Lock(); + throw; + } + } + else + this->RunQuery(&nickcoreupdater, query); + } + catch (const SQLException &ex) + { + Log(LOG_DEBUG) << "OnFindCore: " << ex.GetReason(); + } + } +}; + MODULE_INIT(MySQLLiveModule) diff --git a/modules/extra/m_async_commands.cpp b/modules/extra/m_async_commands.cpp index ddc660ea8..4f251431c 100644 --- a/modules/extra/m_async_commands.cpp +++ b/modules/extra/m_async_commands.cpp @@ -9,11 +9,15 @@ static Mutex main_mutex; class AsynchCommandMutex : public CommandMutex { + bool destroy; public: - AsynchCommandMutex() : CommandMutex() + bool started; + + AsynchCommandMutex(CommandSource &s, Command *c, const std::vector<Anope::string> &p) : CommandMutex(s, c, p), destroy(false), started(false) { commands.push_back(this); - current_command = this; + + this->mutex.Lock(); } ~AsynchCommandMutex() @@ -27,6 +31,8 @@ class AsynchCommandMutex : public CommandMutex void Run() { + this->started = true; + User *u = this->source.u; BotInfo *bi = this->source.owner; @@ -43,6 +49,8 @@ class AsynchCommandMutex : public CommandMutex { FOREACH_MOD(I_OnPostCommand, OnPostCommand(source, command, params)); } + + source.DoReply(); } main_mutex.Unlock(); @@ -50,6 +58,11 @@ class AsynchCommandMutex : public CommandMutex void Lock() { + if (this->destroy) + { + this->Exit(); + } + this->processing = true; me->Notify(); this->mutex.Lock(); @@ -60,13 +73,34 @@ class AsynchCommandMutex : public CommandMutex this->processing = false; main_mutex.Unlock(); } + + void Destroy() + { + this->destroy = true; + } }; class ModuleAsynchCommands : public Module, public Pipe, public AsynchCommandsService { + bool reset; + + void Reset() + { + this->reset = false; + + unsigned count = 0, size = commands.size(); + for (std::list<CommandMutex *>::iterator it = commands.begin(); count < size; ++count, ++it) + { + AsynchCommandMutex *cm = debug_cast<AsynchCommandMutex *>(*it); + cm->Destroy(); + + new AsynchCommandMutex(cm->source, cm->command, cm->params); + } + } + public: - ModuleAsynchCommands(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), Pipe(), AsynchCommandsService(this, "asynch_commands") + ModuleAsynchCommands(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), Pipe(), AsynchCommandsService(this, "asynch_commands"), reset(false) { me = this; @@ -74,26 +108,40 @@ class ModuleAsynchCommands : public Module, public Pipe, public AsynchCommandsSe main_mutex.Lock(); - Implementation i[] = { I_OnPreCommand }; - ModuleManager::Attach(i, this, 1); + Implementation i[] = { I_OnObjectDestroy, I_OnPreCommand }; + ModuleManager::Attach(i, this, 2); ModuleManager::RegisterService(this); } + + void OnObjectDestroy(Base *b) + { + for (std::list<CommandMutex *>::iterator it = commands.begin(), it_end = commands.end(); it != it_end; ++it) + { + AsynchCommandMutex *cm = debug_cast<AsynchCommandMutex *>(*it); + + if (cm->started && (cm->command == b || cm->source.u == b || cm->source.owner == b || cm->source.service == b || cm->source.ci == b)) + cm->Destroy(); + } + + if (current_command == NULL) + this->Reset(); + else + this->reset = true; + } EventReturn OnPreCommand(CommandSource &source, Command *command, const std::vector<Anope::string> ¶ms) { - AsynchCommandMutex *cm = new AsynchCommandMutex(); + AsynchCommandMutex *cm = new AsynchCommandMutex(source, command, params); + try { - cm->mutex.Lock(); - cm->command = command; - cm->source = source; - cm->params = params; - // Give processing to the command thread Log(LOG_DEBUG_2) << "Waiting for command thread " << cm->command->name << " from " << source.u->nick; + current_command = cm; threadEngine.Start(cm); main_mutex.Lock(); + current_command = NULL; return EVENT_STOP; } @@ -108,9 +156,9 @@ class ModuleAsynchCommands : public Module, public Pipe, public AsynchCommandsSe void OnNotify() { - for (std::list<CommandMutex *>::iterator it = commands.begin(), it_end = commands.end(); it != it_end; ++it) + for (std::list<CommandMutex *>::iterator it = commands.begin(), it_end = commands.end(); it != it_end;) { - CommandMutex *cm = *it; + AsynchCommandMutex *cm = debug_cast<AsynchCommandMutex *>(*it++); // Thread engine will pick this up later if (cm->GetExitState() || !cm->processing) @@ -120,11 +168,30 @@ class ModuleAsynchCommands : public Module, public Pipe, public AsynchCommandsSe current_command = cm; // Unlock to give processing back to the command thread - cm->mutex.Unlock(); + if (!cm->started) + { + try + { + threadEngine.Start(cm); + } + catch (const CoreException &) + { + delete cm; + continue; + } + } + else + cm->mutex.Unlock(); // Relock to regain processing once the command thread hangs for any reason main_mutex.Lock(); current_command = NULL; + + if (this->reset) + { + this->Reset(); + return this->OnNotify(); + } } } diff --git a/modules/extra/m_mysql.cpp b/modules/extra/m_mysql.cpp index 12b4dbcc5..7ef4243e6 100644 --- a/modules/extra/m_mysql.cpp +++ b/modules/extra/m_mysql.cpp @@ -50,16 +50,13 @@ class MySQLResult : public SQLResult public: MySQLResult(const Anope::string &q, MYSQL_RES *r) : SQLResult(q), res(r) { - if (!res) - return; + unsigned num_fields = res ? mysql_num_fields(res) : 0; - unsigned num_fields = mysql_num_fields(res); + Log(LOG_DEBUG) << "SQL query " << q << " returned " << num_fields << " fields"; if (!num_fields) return; - Log(LOG_DEBUG) << "SQL query returned " << num_fields << " fields"; - for (MYSQL_ROW row; (row = mysql_fetch_row(res));) { MYSQL_FIELD *fields = mysql_fetch_fields(res); @@ -268,6 +265,8 @@ class ModuleSQL : public Module } this->DThread->Unlock(); + + this->SQLPipe->OnNotify(); } }; @@ -398,8 +397,11 @@ void DispatcherThread::Run() void MySQLPipe::OnNotify() { me->DThread->Lock(); + std::deque<QueryResult> finishedRequests = me->FinishedRequests; + me->FinishedRequests.clear(); + me->DThread->Unlock(); - for (std::deque<QueryResult>::const_iterator it = me->FinishedRequests.begin(), it_end = me->FinishedRequests.end(); it != it_end; ++it) + for (std::deque<QueryResult>::const_iterator it = finishedRequests.begin(), it_end = finishedRequests.end(); it != it_end; ++it) { const QueryResult &qr = *it; @@ -411,9 +413,6 @@ void MySQLPipe::OnNotify() else qr.sqlinterface->OnError(qr.result); } - me->FinishedRequests.clear(); - - me->DThread->Unlock(); } MODULE_INIT(ModuleSQL) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 617029a9b..f606beff6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,5 @@ # Find all the *.cpp files within the current source directory, and sort the list -file(GLOB SRC_SRCS_CPP RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cpp") -set(SRC_SRCS ${SRC_SRCS_C} ${SRC_SRCS_CPP}) +file(GLOB SRC_SRCS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cpp") # If using Windows, add the windows.cpp, the win32 threading engine, and the socket engine to the list if(WIN32) diff --git a/src/base.cpp b/src/base.cpp index d0eff0beb..537770bcd 100644 --- a/src/base.cpp +++ b/src/base.cpp @@ -1,4 +1,5 @@ #include "services.h" +#include "modules.h" Base::Base() { @@ -10,6 +11,8 @@ Base::~Base() { (*it)->Invalidate(); } + + FOREACH_MOD(I_OnObjectDestroy, OnObjectDestroy(this)); } void Base::AddReference(dynamic_reference_base *r) diff --git a/src/bots.cpp b/src/bots.cpp index 4f3ed76c9..254e987a1 100644 --- a/src/bots.cpp +++ b/src/bots.cpp @@ -111,6 +111,10 @@ BotInfo::~BotInfo() } } +void BotInfo::SetIdent(const Anope::string &sident) +{ + this->ident = sident; +} void BotInfo::SetNewNick(const Anope::string &newnick) { diff --git a/src/command.cpp b/src/command.cpp index ddf9a6622..cc23a72a5 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -8,26 +8,6 @@ #include "services.h" #include "modules.h" -CommandSource::~CommandSource() -{ - for (std::list<Anope::string>::iterator it = this->reply.begin(), it_end = this->reply.end(); it != it_end; ++it) - { - const Anope::string &message = *it; - - // Send to the user if the reply is more than one line - if (!this->fantasy || !this->ci || this->reply.size() > 1) - u->SendMessage(this->service, message); - else if (this->ci->botflags.HasFlag(BS_MSG_PRIVMSG)) - ircdproto->SendPrivmsg(this->service, this->ci->name, message.c_str()); - else if (this->ci->botflags.HasFlag(BS_MSG_NOTICE)) - ircdproto->SendNotice(this->service, this->ci->name, message.c_str()); - else if (this->ci->botflags.HasFlag(BS_MSG_NOTICEOPS)) - ircdproto->SendNoticeChanops(this->service, this->ci->c, message.c_str()); - else - u->SendMessage(this->service, message); - } -} - void CommandSource::Reply(const char *message, ...) { va_list args; @@ -52,6 +32,26 @@ void CommandSource::Reply(const Anope::string &message) this->reply.push_back(tok); } +void CommandSource::DoReply() +{ + for (std::list<Anope::string>::iterator it = this->reply.begin(), it_end = this->reply.end(); it != it_end; ++it) + { + const Anope::string &message = *it; + + // Send to the user if the reply is more than one line + if (!this->fantasy || !this->ci || this->reply.size() > 1) + u->SendMessage(this->service, message); + else if (this->ci->botflags.HasFlag(BS_MSG_PRIVMSG)) + ircdproto->SendPrivmsg(this->service, this->ci->name, message.c_str()); + else if (this->ci->botflags.HasFlag(BS_MSG_NOTICE)) + ircdproto->SendNotice(this->service, this->ci->name, message.c_str()); + else if (this->ci->botflags.HasFlag(BS_MSG_NOTICEOPS)) + ircdproto->SendNoticeChanops(this->service, this->ci->c, message.c_str()); + else + u->SendMessage(this->service, message); + } +} + Command::Command(const Anope::string &sname, size_t min_params, size_t max_params, const Anope::string &spermission) : Flags<CommandFlag>(CommandFlagStrings), MaxParams(max_params), MinParams(min_params), name(sname), permission(spermission) { this->module = NULL; diff --git a/src/commands.cpp b/src/commands.cpp index e3a52a503..6944ac31e 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -168,6 +168,8 @@ void mod_run_cmd(BotInfo *bi, User *u, Command *c, const Anope::string &command, { FOREACH_MOD(I_OnPostCommand, OnPostCommand(source, c, params)); } + + source.DoReply(); } /** diff --git a/src/modulemanager.cpp b/src/modulemanager.cpp index 2c716acf6..d530b6e46 100644 --- a/src/modulemanager.cpp +++ b/src/modulemanager.cpp @@ -400,7 +400,7 @@ void ModuleManager::UnloadAll() Module *m = *it++; if (static_cast<MODType>(i) == m->type) - DeleteModule(m); + UnloadModule(m, NULL); } } } diff --git a/src/threadengines/threadengine_pthread.cpp b/src/threadengines/threadengine_pthread.cpp index e8242bb82..f28c43846 100644 --- a/src/threadengines/threadengine_pthread.cpp +++ b/src/threadengines/threadengine_pthread.cpp @@ -43,6 +43,7 @@ void Thread::Join() */ void Thread::Exit() { + this->SetExitState(); pthread_exit(0); } diff --git a/src/threadengines/threadengine_win32.cpp b/src/threadengines/threadengine_win32.cpp index 218f711c4..adefab800 100644 --- a/src/threadengines/threadengine_win32.cpp +++ b/src/threadengines/threadengine_win32.cpp @@ -35,6 +35,7 @@ void Thread::Join() */ void Thread::Exit() { + this->SetExitState(); ExitThread(0); } |