]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/base/CodeContext.h
2 * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
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.
9 #ifndef SQUID_BASE_CODE_CONTEXT_H
10 #define SQUID_BASE_CODE_CONTEXT_H
12 #include "base/InstanceId.h"
13 #include "base/RefCount.h"
17 /// Interface for reporting what Squid code is working on.
18 /// Such reports are usually requested outside creator's call stack.
19 /// They are especially useful for attributing low-level errors to transactions.
20 class CodeContext
: public RefCountable
23 typedef RefCount
<CodeContext
> Pointer
;
25 /// \returns the known global context or, to indicate unknown context, nil
26 static const Pointer
&Current();
28 /// forgets the current context, setting it to nil/unknown
31 /// changes the current context; nil argument sets it to nil/unknown
32 static void Reset(const Pointer
);
34 virtual ~CodeContext() {}
36 /// \returns a small, permanent ID of the current context
37 /// gists persist forever and are suitable for passing to other SMP workers
38 virtual ScopedId
codeContextGist() const = 0;
40 /// appends human-friendly context description line(s) to a cache.log record
41 virtual std::ostream
&detailCodeContext(std::ostream
&os
) const = 0;
44 static void ForgetCurrent();
45 static void Entering(const Pointer
&codeCtx
);
46 static void Leaving();
49 /// by default, only small context gist is printed
51 std::ostream
&operator <<(std::ostream
&os
, const CodeContext
&ctx
)
53 return os
<< ctx
.codeContextGist();
56 /* convenience context-reporting wrappers that also reduce linking problems */
57 std::ostream
&CurrentCodeContextBrief(std::ostream
&os
);
58 std::ostream
&CurrentCodeContextDetail(std::ostream
&os
);
60 /// Convenience class that automatically restores the current/outer CodeContext
61 /// when leaving the scope of the new-context following/inner code. \see Run().
62 class CodeContextGuard
65 CodeContextGuard(const CodeContext::Pointer
&newContext
): savedCodeContext(CodeContext::Current()) { CodeContext::Reset(newContext
); }
66 ~CodeContextGuard() { CodeContext::Reset(savedCodeContext
); }
68 // no copying of any kind (for simplicity and to prevent accidental copies)
69 CodeContextGuard(CodeContextGuard
&&) = delete;
71 CodeContext::Pointer savedCodeContext
;
74 /// Executes service `callback` in `callbackContext`. If an exception occurs,
75 /// the callback context is preserved, so that the exception is associated with
76 /// the callback that triggered them (rather than with the service).
78 /// Service code running in its own service context should use this function.
79 template <typename Fun
>
81 CallBack(const CodeContext::Pointer
&callbackContext
, Fun
&&callback
)
83 // TODO: Consider catching exceptions and letting CodeContext handle them.
84 const auto savedCodeContext(CodeContext::Current());
85 CodeContext::Reset(callbackContext
);
87 CodeContext::Reset(savedCodeContext
);
90 /// Executes `service` in `serviceContext` but due to automatic caller context
91 /// restoration, service exceptions are associated with the caller that suffered
92 /// from (and/or caused) them (rather than with the service itself).
94 /// Service code running in caller's context should use this function to escape
95 /// into service context (e.g., for submitting caller-agnostic requests).
96 template <typename Fun
>
98 CallService(const CodeContext::Pointer
&serviceContext
, Fun
&&service
)
100 // TODO: Consider catching exceptions and letting CodeContext handle them.
101 CodeContextGuard
guard(serviceContext
);
105 /// Executes context `creator` in the service context. If an exception occurs,
106 /// the creator context is preserved, so that the exception is associated with
107 /// the creator that triggered them (rather than with the service).
109 /// Service code running in its own context should use this function to create
110 /// new code contexts. TODO: Use or, if this pattern is not repeated, remove.
111 template <typename Fun
>
113 CallContextCreator(Fun
&&creator
)
115 const auto savedCodeContext(CodeContext::Current());
117 CodeContext::Reset(savedCodeContext
);