blob: a1d76e334b9539d87bbd3cbb9c08c72dcb9f19c2 [file] [log] [blame]
wub3e6cf912021-06-18 12:12:39 -07001// Copyright 2021 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef QUICHE_QUIC_CORE_QUIC_CONNECTION_CONTEXT_H_
6#define QUICHE_QUIC_CORE_QUIC_CONNECTION_CONTEXT_H_
7
8#include "absl/strings/str_format.h"
9#include "absl/strings/string_view.h"
10#include "quic/platform/api/quic_export.h"
11#include "common/platform/api/quiche_logging.h"
12
13namespace quic {
14
15// QuicConnectionTracer is responsible for emit trace messages for a single
16// QuicConnection.
17// QuicConnectionTracer is part of the QuicConnectionContext.
18class QUIC_EXPORT_PRIVATE QuicConnectionTracer {
19 public:
20 virtual ~QuicConnectionTracer() = default;
21
22 // Emit a trace message from a string literal. The trace may simply remember
23 // the address of the literal in this function and read it at a later time.
24 virtual void PrintLiteral(const char* literal) = 0;
25
26 // Emit a trace message from a string_view. Unlike PrintLiteral, this function
27 // will not read |s| after it returns.
28 virtual void PrintString(absl::string_view s) = 0;
29
30 // Emit a trace message from printf-style arguments.
31 template <typename... Args>
32 void Printf(const absl::FormatSpec<Args...>& format, const Args&... args) {
33 std::string s = absl::StrFormat(format, args...);
34 PrintString(s);
35 }
wubeb6dec72021-07-21 18:23:53 -070036
37 private:
38 friend class QuicConnectionContextSwitcher;
39
40 // Called by QuicConnectionContextSwitcher, when |this| becomes the current
41 // thread's QUIC connection tracer.
42 //
43 // Activate/Deactivate are only called by QuicConnectionContextSwitcher's
44 // constructor/destructor, they always come in pairs.
45 virtual void Activate() {}
46
47 // Called by QuicConnectionContextSwitcher, when |this| stops from being the
48 // current thread's QUIC connection tracer.
49 //
50 // Activate/Deactivate are only called by QuicConnectionContextSwitcher's
51 // constructor/destructor, they always come in pairs.
52 virtual void Deactivate() {}
wub3e6cf912021-06-18 12:12:39 -070053};
54
wub59781a82021-11-30 12:55:01 -080055// QuicBugListener is a helper class for implementing QUIC_BUG. The QUIC_BUG
56// implementation can send the bug information into quic::CurrentBugListener().
57class QUIC_EXPORT_PRIVATE QuicBugListener {
58 public:
59 virtual ~QuicBugListener() = default;
60 virtual void OnQuicBug(const char* bug_id, const char* file, int line,
61 absl::string_view bug_message) = 0;
62};
63
wub3e6cf912021-06-18 12:12:39 -070064// QuicConnectionContext is a per-QuicConnection context that includes
65// facilities useable by any part of a QuicConnection. A QuicConnectionContext
66// is owned by a QuicConnection.
67//
68// The 'top-level' QuicConnection functions are responsible for maintaining the
69// thread-local QuicConnectionContext pointer, such that any function called by
70// them(directly or indirectly) can access the context.
71//
72// Like QuicConnection, all facilities in QuicConnectionContext are assumed to
73// be called from a single thread at a time, they are NOT thread-safe.
74struct QUIC_EXPORT_PRIVATE QuicConnectionContext final {
75 // Get the context on the current executing thread. nullptr if the current
76 // function is not called from a 'top-level' QuicConnection function.
77 static QuicConnectionContext* Current();
78
79 std::unique_ptr<QuicConnectionTracer> tracer;
wub59781a82021-11-30 12:55:01 -080080 std::unique_ptr<QuicBugListener> bug_listener;
wub3e6cf912021-06-18 12:12:39 -070081};
82
83// QuicConnectionContextSwitcher is a RAII object used for maintaining the
84// thread-local QuicConnectionContext pointer.
85class QUIC_EXPORT_PRIVATE QuicConnectionContextSwitcher final {
86 public:
87 // The constructor switches from QuicConnectionContext::Current() to
88 // |new_context|.
89 explicit QuicConnectionContextSwitcher(QuicConnectionContext* new_context);
90
91 // The destructor switches from QuicConnectionContext::Current() back to the
92 // old context.
93 ~QuicConnectionContextSwitcher();
94
95 private:
96 QuicConnectionContext* old_context_;
97};
98
99// Emit a trace message from a string literal to the current tracer(if any).
100inline void QUIC_TRACELITERAL(const char* literal) {
101 QuicConnectionContext* current = QuicConnectionContext::Current();
102 if (current && current->tracer) {
103 current->tracer->PrintLiteral(literal);
104 }
105}
106
107// Emit a trace message from a string_view to the current tracer(if any).
108inline void QUIC_TRACESTRING(absl::string_view s) {
109 QuicConnectionContext* current = QuicConnectionContext::Current();
110 if (current && current->tracer) {
111 current->tracer->PrintString(s);
112 }
113}
114
115// Emit a trace message from printf-style arguments to the current tracer(if
116// any).
117template <typename... Args>
118void QUIC_TRACEPRINTF(const absl::FormatSpec<Args...>& format,
119 const Args&... args) {
120 QuicConnectionContext* current = QuicConnectionContext::Current();
121 if (current && current->tracer) {
122 current->tracer->Printf(format, args...);
123 }
124}
125
wub59781a82021-11-30 12:55:01 -0800126inline QuicBugListener* CurrentBugListener() {
127 QuicConnectionContext* current = QuicConnectionContext::Current();
128 return (current != nullptr) ? current->bug_listener.get() : nullptr;
129}
130
wub3e6cf912021-06-18 12:12:39 -0700131} // namespace quic
132
133#endif // QUICHE_QUIC_CORE_QUIC_CONNECTION_CONTEXT_H_