/* * InspIRCd -- Internet Relay Chat Daemon * * Copyright (C) 2015 Attila Molnar * Copyright (C) 2013, 2020 Sadie Powell * Copyright (C) 2012 Robby * Copyright (C) 2011 jackmcbarn * Copyright (C) 2009 Daniel De Graaf * Copyright (C) 2007 Dennis Friis * Copyright (C) 2007 Craig Edwards * * This file is part of InspIRCd. InspIRCd is free software: you can * redistribute it and/or modify it under the terms of the GNU General Public * License as published by the Free Software Foundation, version 2. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "inspircd.h" #ifdef INSPIRCD_ENABLE_RTTI # include #endif Cullable::Cullable() { #ifdef INSPIRCD_ENABLE_RTTI if (ServerInstance) { ServerInstance->Logs.Debug("CULLLIST", "Cullable::+%s @%p", typeid(*this).name(), static_cast(this)); } #endif } Cullable::~Cullable() { #ifdef INSPIRCD_ENABLE_RTTI if (ServerInstance) { ServerInstance->Logs.Debug("CULLLIST", "Cullable::~%s @%p", typeid(*this).name(), static_cast(this)); } #endif } Cullable::Result Cullable::Cull() { #ifdef INSPIRCD_ENABLE_RTTI if (ServerInstance) { ServerInstance->Logs.Debug("CULLLIST", "Cullable::-%s @%p", typeid(*this).name(), static_cast(this)); } #endif return {}; } void CullList::Apply() { std::vector working; while (!SQlist.empty()) { working.swap(SQlist); for (auto* u : working) { ServerInstance->SNO.WriteGlobalSno('a', "User {} SendQ exceeds connect class maximum of {}", u->nick, u->GetClass()->hardsendqmax); ServerInstance->Users.QuitUser(u, "SendQ exceeded"); } working.clear(); } std::set gone; std::vector queue; queue.reserve(list.size() + 32); for (auto* c : list) { if (gone.insert(c).second) { #ifdef INSPIRCD_ENABLE_RTTI ServerInstance->Logs.Debug("CULLLIST", "Deleting %s @%p", typeid(*c).name(), static_cast(c)); #else ServerInstance->Logs.Debug("CULLLIST", "Deleting @%p", static_cast(c)); #endif c->Cull(); queue.push_back(c); } else { #ifdef INSPIRCD_ENABLE_RTTI ServerInstance->Logs.Debug("CULLLIST", "WARNING: Object %s @%p culled twice!", typeid(*c).name(), static_cast(c)); #else ServerInstance->Logs.Debug("CULLLIST", "WARNING: Object @%p culled twice!", static_cast(c)); #endif } } list.clear(); for (auto* c : queue) delete c; if (!list.empty()) { ServerInstance->Logs.Debug("CULLLIST", "WARNING: Objects added to cull list in a destructor"); Apply(); } } void ActionList::Run() { for (auto* action : list) action->Call(); list.clear(); }