]> git.ipfire.org Git - thirdparty/squid.git/blob - src/base/CodeContext.cc
Source Format Enforcement (#963)
[thirdparty/squid.git] / src / base / CodeContext.cc
1 /*
2 * Copyright (C) 1996-2022 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 code_contexts for details.
7 */
8
9 #include "squid.h"
10 #include "base/CodeContext.h"
11 #include "Debug.h"
12
13 /// represents a being-forgotten CodeContext (while it may be being destroyed)
14 class FadingCodeContext: public CodeContext
15 {
16 public:
17 /* CodeContext API */
18 virtual ScopedId codeContextGist() const override { return gist; }
19 virtual std::ostream &detailCodeContext(std::ostream &os) const override { return os << gist; }
20
21 ScopedId gist; ///< identifies the being-forgotten CodeContext
22 };
23
24 /// guarantees the forever existence of the pointer, starting from the first use
25 static CodeContext::Pointer &
26 Instance()
27 {
28 static const auto Instance = new CodeContext::Pointer(nullptr);
29 return *Instance;
30 }
31
32 const CodeContext::Pointer &
33 CodeContext::Current()
34 {
35 return Instance();
36 }
37
38 /// Forgets the current known context, possibly triggering its destruction.
39 /// Preserves the gist of the being-forgotten context during its destruction.
40 /// Knows nothing about the next context -- the caller must set it.
41 void
42 CodeContext::ForgetCurrent()
43 {
44 static const RefCount<FadingCodeContext> fadingCodeContext = new FadingCodeContext();
45 auto &current = Instance();
46 assert(current);
47 fadingCodeContext->gist = current->codeContextGist();
48 current = fadingCodeContext;
49 }
50
51 /// Switches the current context to the given known context. Improves debugging
52 /// output by replacing omni-directional "Reset" with directional "Entering".
53 void
54 CodeContext::Entering(const Pointer &codeCtx)
55 {
56 auto &current = Instance();
57 if (current)
58 ForgetCurrent(); // ensure orderly closure of the old context
59 current = codeCtx;
60 debugs(1, 5, codeCtx->codeContextGist());
61 }
62
63 /// Forgets the current known context. Improves debugging output by replacing
64 /// omni-directional "Reset" with directional "Leaving".
65 void
66 CodeContext::Leaving()
67 {
68 ForgetCurrent();
69 auto &current = Instance();
70 debugs(1, 7, *current);
71 current = nullptr;
72 }
73
74 void
75 CodeContext::Reset()
76 {
77 if (Instance())
78 Leaving();
79 }
80
81 void
82 CodeContext::Reset(const Pointer codeCtx)
83 {
84 if (codeCtx == Current())
85 return; // context has not actually changed
86
87 if (!codeCtx)
88 return Leaving();
89
90 Entering(codeCtx);
91 }
92
93 std::ostream &
94 CurrentCodeContextDetail(std::ostream &os)
95 {
96 if (const auto ctx = CodeContext::Current())
97 ctx->detailCodeContext(os);
98 return os;
99 }
100