]>
Commit | Line | Data |
---|---|---|
ccfbe8f4 | 1 | /* |
f70aedc4 | 2 | * Copyright (C) 1996-2021 The Squid Software Foundation and contributors |
ccfbe8f4 AR |
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 ¤t = 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 ¤t = 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 ¤t = 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 |