]> git.ipfire.org Git - thirdparty/squid.git/blob - src/base/JobWait.cc
Source Format Enforcement (#1234)
[thirdparty/squid.git] / src / base / JobWait.cc
1 /*
2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 #include "squid.h"
10 #include "base/AsyncJobCalls.h"
11 #include "base/JobWait.h"
12
13 #include <cassert>
14 #include <iostream>
15
16 JobWaitBase::JobWaitBase() = default;
17
18 JobWaitBase::~JobWaitBase()
19 {
20 cancel("owner gone");
21 }
22
23 void
24 JobWaitBase::start_(const AsyncJob::Pointer aJob, const AsyncCall::Pointer aCall)
25 {
26 // Invariant: The wait will be over. We cannot guarantee that the job will
27 // call the callback, of course, but we can check these prerequisites.
28 assert(aCall);
29 assert(aJob.valid());
30
31 // "Double" waiting state leads to conflicting/mismatching callbacks
32 // detailed in finish(). Detect that bug ASAP.
33 assert(!waiting());
34
35 assert(!callback_);
36 assert(!job_);
37 callback_ = aCall;
38 job_ = aJob;
39
40 AsyncJob::Start(job_.get());
41 }
42
43 void
44 JobWaitBase::finish()
45 {
46 // Unexpected callbacks might result in disasters like secrets exposure,
47 // data corruption, or expensive message routing mistakes when the callback
48 // info is applied to the wrong message part or acted upon prematurely.
49 assert(waiting());
50 clear();
51 }
52
53 void
54 JobWaitBase::cancel(const char *reason)
55 {
56 if (callback_) {
57 callback_->cancel(reason);
58
59 // Instead of AsyncJob, the class parameter could be Job. That would
60 // avoid runtime child-to-parent CbcPointer conversion overheads, but
61 // complicate support for Jobs with virtual AsyncJob bases (GCC error:
62 // "pointer to member conversion via virtual base AsyncJob") and also
63 // cache-log "Job::handleStopRequest()" with a non-existent class name.
64 CallJobHere(callback_->debugSection, callback_->debugLevel, job_, AsyncJob, handleStopRequest);
65
66 clear();
67 }
68 }
69
70 void
71 JobWaitBase::print(std::ostream &os) const
72 {
73 // use a backarrow to emphasize that this is a callback: call24<-job6
74 if (callback_)
75 os << callback_->id << "<-";
76 if (const auto rawJob = job_.get())
77 os << rawJob->id;
78 else
79 os << job_; // raw pointer of a gone job may still be useful for triage
80 }
81