diff options
author | Adam <Adam@anope.org> | 2015-09-17 10:07:30 -0400 |
---|---|---|
committer | Adam <Adam@anope.org> | 2015-09-17 10:07:30 -0400 |
commit | 1ac4a1d9a56141d18b3e8a32fe165535031a4c67 (patch) | |
tree | 5ee8af16acaaad7307732213afaf9eaa333a76d2 /src/channels.cpp | |
parent | 8d13a355cd9b851b5cf9f6012c77b2af68a039f1 (diff) |
Defer channel deletion until after i/o. There are some edge cases with events kicking users mid-event that can delete them.
Diffstat (limited to 'src/channels.cpp')
-rw-r--r-- | src/channels.cpp | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/src/channels.cpp b/src/channels.cpp index a794f5126..8e9b3be94 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -27,6 +27,7 @@ #include "uplink.h" channel_map ChannelList; +std::vector<Channel *> Channel::deleting; Channel::Channel(const Anope::string &nname, time_t ts) { @@ -168,8 +169,8 @@ void Channel::DeleteUser(User *user) Log(LOG_DEBUG) << "Channel::DeleteUser() tried to delete non-existent channel " << this->name << " from " << user->nick << "'s channel list"; delete cu; - if (this->CheckDelete()) - delete this; + if (std::find(deleting.begin(), deleting.end(), this) == deleting.end()) + deleting.push_back(this); } ChanUserContainer *Channel::FindUser(User *u) const @@ -759,12 +760,11 @@ void Channel::KickInternal(const MessageSource &source, const Anope::string &nic return; } - Anope::string this_name = this->name; ChannelStatus status = cu->status; FOREACH_MOD(OnPreUserKicked, (source, cu, reason)); - this->DeleteUser(target); /* This can delete this; */ - FOREACH_MOD(OnUserKicked, (source, target, this_name, status, reason)); + this->DeleteUser(target); + FOREACH_MOD(OnUserKicked, (source, target, this->name, status, reason)); } bool Channel::Kick(BotInfo *bi, User *u, const char *reason, ...) @@ -939,3 +939,15 @@ Channel *Channel::FindOrCreate(const Anope::string &name, bool &created, time_t return chan; } +void Channel::DeleteChannels() +{ + for (unsigned int i = 0; i < deleting.size(); ++i) + { + Channel *c = deleting[i]; + + if (c->CheckDelete()) + delete c; + } + deleting.clear(); +} + |