diff options
author | Adam <Adam@anope.org> | 2013-01-03 11:41:32 -0500 |
---|---|---|
committer | Adam <Adam@anope.org> | 2013-01-03 12:34:01 -0500 |
commit | 098157dca8a4aecc18294cbc31cbe5ee95b35a94 (patch) | |
tree | 654f00f21e151ba9007ca8eb044a78fef1bd6e39 /src | |
parent | 827469600e8cf98fea7aec09ceaa77a097300b72 (diff) |
Don't delete users immediately when quit or killed, instead wait until message processing is done
Diffstat (limited to 'src')
-rw-r--r-- | src/command.cpp | 9 | ||||
-rw-r--r-- | src/messages.cpp | 2 | ||||
-rw-r--r-- | src/nickalias.cpp | 2 | ||||
-rw-r--r-- | src/servers.cpp | 3 | ||||
-rw-r--r-- | src/socket_transport.cpp | 37 | ||||
-rw-r--r-- | src/uplink.cpp | 9 | ||||
-rw-r--r-- | src/users.cpp | 50 |
7 files changed, 64 insertions, 48 deletions
diff --git a/src/command.cpp b/src/command.cpp index 887967626..c737897e5 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -262,13 +262,10 @@ void RunCommand(CommandSource &source, const Anope::string &message) return; } - bool had_u = source.GetUser(), had_nc = source.nc; - Reference<User> user_reference(source.GetUser()); Reference<NickCore> nc_reference(source.nc); c->Execute(source, params); - if (had_u == user_reference && had_nc == nc_reference) - { - FOREACH_MOD(I_OnPostCommand, OnPostCommand(source, c, params)); - } + if (!nc_reference) + source.nc = NULL; + FOREACH_MOD(I_OnPostCommand, OnPostCommand(source, c, params)); } diff --git a/src/messages.cpp b/src/messages.cpp index 79a32347b..68ba704d1 100644 --- a/src/messages.cpp +++ b/src/messages.cpp @@ -351,7 +351,7 @@ void Quit::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) na->last_quit = reason; } FOREACH_MOD(I_OnUserQuit, OnUserQuit(user, reason)); - delete user; + user->Quit(reason); return; } diff --git a/src/nickalias.cpp b/src/nickalias.cpp index 4ce861943..cee24fb87 100644 --- a/src/nickalias.cpp +++ b/src/nickalias.cpp @@ -88,7 +88,7 @@ void NickAlias::Release() User *u = User::Find(this->nick); if (u && u->server == Me) { - delete u; + u->Quit(); } } diff --git a/src/servers.cpp b/src/servers.cpp index 392e494a0..fd3fe490a 100644 --- a/src/servers.cpp +++ b/src/servers.cpp @@ -137,7 +137,8 @@ Server::~Server() na->last_quit = this->quit_reason; } - delete u; + u->Quit(this->quit_reason); + u->server = NULL; } } diff --git a/src/socket_transport.cpp b/src/socket_transport.cpp index 4af3668a3..98da3e605 100644 --- a/src/socket_transport.cpp +++ b/src/socket_transport.cpp @@ -33,34 +33,9 @@ bool BufferedSocket::ProcessRead() return false; tbuffer[len] = 0; + this->read_buffer.append(tbuffer); this->recv_len = len; - Anope::string sbuffer = this->extra_buf; - sbuffer += tbuffer; - this->extra_buf.clear(); - size_t lastnewline = sbuffer.rfind('\n'); - if (lastnewline == Anope::string::npos) - { - this->extra_buf = sbuffer; - return true; - } - if (lastnewline < sbuffer.length() - 1) - { - this->extra_buf = sbuffer.substr(lastnewline); - this->extra_buf.trim(); - sbuffer = sbuffer.substr(0, lastnewline); - } - - sepstream stream(sbuffer, '\n'); - - Anope::string tbuf; - while (stream.GetToken(tbuf)) - { - tbuf.trim(); - if (!Read(tbuf)) - return false; - } - return true; } @@ -76,9 +51,15 @@ bool BufferedSocket::ProcessWrite() return true; } -bool BufferedSocket::Read(const Anope::string &buf) +const Anope::string BufferedSocket::GetLine() { - return false; + size_t s = this->read_buffer.find('\n'); + if (s == Anope::string::npos) + return ""; + Anope::string str = this->read_buffer.substr(0, s + 1); + this->read_buffer.erase(0, s + 1); + this->read_buffer.ltrim(); + return str.trim(); } void BufferedSocket::Write(const char *buffer, size_t l) diff --git a/src/uplink.cpp b/src/uplink.cpp index 9490329b3..7c9c77888 100644 --- a/src/uplink.cpp +++ b/src/uplink.cpp @@ -116,9 +116,14 @@ UplinkSocket::~UplinkSocket() } } -bool UplinkSocket::Read(const Anope::string &buf) +bool UplinkSocket::ProcessRead() { - Anope::Process(buf); + BufferedSocket::ProcessRead(); + for (Anope::string buf; (buf = this->GetLine()).empty() == false;) + { + Anope::Process(buf); + User::QuitUsers(); + } return true; } diff --git a/src/users.cpp b/src/users.cpp index 0e2ed34f9..1f70b47b4 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -30,12 +30,15 @@ int OperCount = 0; unsigned MaxUserCount = 0; time_t MaxUserTime = 0; +std::list<User *> User::quitting_users; + User::User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ssignon, const Anope::string &smodes, const Anope::string &suid) { if (snick.empty() || sident.empty() || shost.empty()) throw CoreException("Bad args passed to User::User"); /* we used to do this by calloc, no more. */ + quit = false; server = NULL; invalid_pw_count = invalid_pw_time = lastmemosend = lastnickreg = lastmail = 0; on_access = false; @@ -79,8 +82,7 @@ User::User(const Anope::string &snick, const Anope::string &sident, const Anope: bool exempt = false; if (server && server->IsULined()) exempt = true; - Reference<User> user = this; - FOREACH_MOD(I_OnUserConnect, OnUserConnect(user, exempt)); + FOREACH_MOD(I_OnUserConnect, OnUserConnect(this, exempt)); } void User::ChangeNick(const Anope::string &newnick, time_t ts) @@ -229,10 +231,11 @@ void User::SetRealname(const Anope::string &srealname) User::~User() { - Log(LOG_DEBUG_2) << "User::~User() called"; - - Log(this, "disconnect") << "(" << this->realname << ") " << "disconnected from the network (" << this->server->GetName() << ")"; - --this->server->users; + if (this->server != NULL) + { + Log(this, "disconnect") << "(" << this->realname << ") disconnected from the network (" << this->server->GetName() << ")"; + --this->server->users; + } FOREACH_MOD(I_OnUserLogoff, OnUserLogoff(this)); @@ -252,8 +255,6 @@ User::~User() NickAlias *na = NickAlias::Find(this->nick); if (na) na->OnCancel(this); - - Log(LOG_DEBUG_2) << "User::~User() done"; } void User::SendMessage(const BotInfo *source, const char *fmt, ...) @@ -752,6 +753,12 @@ void User::Kill(const Anope::string &source, const Anope::string &reason) void User::KillInternal(const Anope::string &source, const Anope::string &reason) { + if (this->quit) + { + Log(LOG_DEBUG) << "Duplicate quit for " << this->nick; + return; + } + Log(this, "killed") << "was killed by " << source << " (Reason: " << reason << ")"; NickAlias *na = NickAlias::Find(this->nick); @@ -761,7 +768,25 @@ void User::KillInternal(const Anope::string &source, const Anope::string &reason na->last_quit = reason; } - delete this; + this->quit = true; + quitting_users.push_back(this); +} + +void User::Quit(const Anope::string &reason) +{ + if (this->quit) + { + Log(LOG_DEBUG) << "Duplicate quit for " << this->nick; + return; + } + + this->quit = true; + quitting_users.push_back(this); +} + +bool User::Quitting() const +{ + return this->quit; } Anope::string User::Mask() const @@ -829,3 +854,10 @@ User* User::Find(const Anope::string &name, bool nick_only) return NULL; } +void User::QuitUsers() +{ + for (std::list<User *>::iterator it = quitting_users.begin(), it_end = quitting_users.end(); it != it_end; ++it) + delete *it; + quitting_users.clear(); +} + |