/* * Copyright (C) 1996-2023 The Squid Software Foundation and contributors * * Squid software is distributed under GPLv2+ license and includes * contributions from numerous individuals and organizations. * Please see the COPYING and CONTRIBUTORS files for details. */ #include "squid.h" #include "base/AsyncCall.h" #include "base/AsyncCallQueue.h" #include "base/CodeContext.h" #include "cbdata.h" #include "debug/Stream.h" #include InstanceIdDefinitions(AsyncCall, "call"); /* AsyncCall */ AsyncCall::AsyncCall(int aDebugSection, int aDebugLevel, const char *aName): name(aName), codeContext(CodeContext::Current()), debugSection(aDebugSection), debugLevel(aDebugLevel), theNext(nullptr), isCanceled(nullptr) { debugs(debugSection, debugLevel, "The AsyncCall " << name << " constructed, this=" << this << " [" << id << ']'); } AsyncCall::~AsyncCall() { assert(!theNext); // AsyncCallQueue must clean } void AsyncCall::make() { debugs(debugSection, debugLevel, "make call " << name << " [" << id << ']'); if (canFire()) { fire(); return; } if (!isCanceled) // we did not cancel() when returning false from canFire() isCanceled = "unknown reason"; debugs(debugSection, debugLevel, "will not call " << name << " [" << id << ']' << " because of " << isCanceled); } bool AsyncCall::cancel(const char *reason) { debugs(debugSection, debugLevel, "will not call " << name << " [" << id << "] " << (isCanceled ? "also " : "") << "because " << reason); isCanceled = reason; return false; } bool AsyncCall::canFire() { return !isCanceled; } // TODO: make this method const by providing a const getDialer() void AsyncCall::print(std::ostream &os) { os << name; if (const CallDialer *dialer = getDialer()) dialer->print(os); else os << "(?" << this << "?)"; } void AsyncCall::dequeue(AsyncCall::Pointer &head, AsyncCall::Pointer &prev) { if (prev != nullptr) prev->setNext(Next()); else head = Next(); setNext(nullptr); } bool ScheduleCall(const char *fileName, int fileLine, const AsyncCall::Pointer &call) { debugs(call->debugSection, call->debugLevel, fileName << "(" << fileLine << ") will call " << *call << " [" << call->id << ']' ); // Support callback creators that did not get their context from service A, // but the current caller (service B) got that context from another source. if (!call->codeContext) call->codeContext = CodeContext::Current(); AsyncCallQueue::Instance().schedule(call); return true; }