]>
Commit | Line | Data |
---|---|---|
bbc27441 | 1 | /* |
b8ae064d | 2 | * Copyright (C) 1996-2023 The Squid Software Foundation and contributors |
bbc27441 AJ |
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 | ||
ff9d9458 FC |
9 | #ifndef SQUID_SRC_BASE_INSTANCEID_H |
10 | #define SQUID_SRC_BASE_INSTANCEID_H | |
8b110b48 | 11 | |
8b110b48 AR |
12 | #include <iosfwd> |
13 | ||
ccfbe8f4 AR |
14 | /// Represents an InstanceId<C> value independent from its owner class C. These |
15 | /// "detached" IDs can be stored by and exchanged among C-unaware users at the | |
16 | /// price of storing a short scope c-string (that InstanceIds hard-code instead) | |
17 | /// and, in some cases, using more bits/space than InstanceId<C>::value uses. | |
18 | class ScopedId | |
19 | { | |
20 | public: | |
21 | ScopedId(): scope(nullptr), value(0) {} | |
22 | explicit ScopedId(const char *s): scope(s), value(0) {} | |
23 | // when the values is zero/unknown, use other constructors | |
24 | ScopedId(const char *s, uint64_t v): scope(s), value(v) { /* assert(value) */ } | |
25 | ||
26 | /// either the prefix() of the InstanceId object that we were detached from | |
27 | /// or, for 0 values, some other description (with endless lifetime) or nil | |
28 | const char *scope; | |
29 | ||
30 | /// either the value of the InstanceId object that we were detached from | |
31 | /// or, if our creator did not know the exact value, zero | |
32 | uint64_t value; | |
33 | }; | |
34 | ||
4c3f7931 | 35 | std::ostream &operator <<(std::ostream &os, const ScopedId &id); |
ccfbe8f4 | 36 | |
7cfd3a41 | 37 | typedef unsigned int InstanceIdDefaultValueType; |
8b110b48 AR |
38 | /** Identifier for class instances |
39 | * - unique IDs for a large number of concurrent instances, but may wrap; | |
40 | * - useful for debugging and insecure request/response matching; | |
41 | * - sequential IDs within a class except when wrapping; | |
42 | * - always positive IDs. | |
9837567d | 43 | * TODO: add creation/destruction debugging? |
8b110b48 | 44 | */ |
7cfd3a41 | 45 | template <class Class, class ValueType = InstanceIdDefaultValueType> |
8b110b48 AR |
46 | class InstanceId |
47 | { | |
48 | public: | |
7cfd3a41 | 49 | typedef ValueType Value; ///< id storage type |
8b110b48 | 50 | |
827df6a4 | 51 | InstanceId() {change();} |
8b110b48 AR |
52 | |
53 | operator Value() const { return value; } | |
54 | bool operator ==(const InstanceId &o) const { return value == o.value; } | |
55 | bool operator !=(const InstanceId &o) const { return !(*this == o); } | |
f2e41480 | 56 | void change(); |
8b110b48 | 57 | |
ccfbe8f4 | 58 | /// writes a compact text representation of the ID |
827df6a4 | 59 | std::ostream &print(std::ostream &) const; |
8b110b48 | 60 | |
ccfbe8f4 AR |
61 | // TODO: Refactor into static Scope(). |
62 | /// \returns Class-specific nickname (with endless lifetime) | |
827df6a4 | 63 | const char * prefix() const; |
f2e41480 | 64 | |
ccfbe8f4 AR |
65 | /// \returns a copy of the ID usable outside our Class context |
66 | ScopedId detach() const { return ScopedId(prefix(), value); } | |
67 | ||
8b110b48 | 68 | public: |
7cfd3a41 | 69 | Value value = Value(); ///< instance identifier |
8b110b48 AR |
70 | |
71 | private: | |
827df6a4 AJ |
72 | InstanceId(const InstanceId &); ///< not implemented; IDs are unique |
73 | InstanceId& operator=(const InstanceId &); ///< not implemented | |
8b110b48 AR |
74 | }; |
75 | ||
7cfd3a41 EB |
76 | /// An InstanceIdDefinitions() helper. Avoid direct use. |
77 | #define InstanceIdDefinitions3(Class, pfx, ValueType, ...) \ | |
827df6a4 | 78 | template<> const char * \ |
7cfd3a41 | 79 | InstanceId<Class, ValueType>::prefix() const { \ |
f2e41480 AJ |
80 | return pfx; \ |
81 | } \ | |
8b110b48 | 82 | template<> std::ostream & \ |
7cfd3a41 | 83 | InstanceId<Class, ValueType>::print(std::ostream &os) const { \ |
f2e41480 AJ |
84 | return os << pfx << value; \ |
85 | } \ | |
86 | template<> void \ | |
7cfd3a41 EB |
87 | InstanceId<Class, ValueType>::change() { \ |
88 | static auto Last = Value(); \ | |
f2e41480 | 89 | value = ++Last ? Last : ++Last; \ |
cd3f0ed7 | 90 | } |
8b110b48 | 91 | |
7cfd3a41 EB |
92 | /// convenience macro to instantiate Class-specific stuff in .cc files |
93 | #define InstanceIdDefinitions(...) InstanceIdDefinitions3(__VA_ARGS__, InstanceIdDefaultValueType) | |
94 | ||
8b110b48 | 95 | /// print the id |
7cfd3a41 | 96 | template <class Class, class ValueType> |
8b110b48 | 97 | inline |
7cfd3a41 | 98 | std::ostream &operator <<(std::ostream &os, const InstanceId<Class, ValueType> &id) |
ab745b44 | 99 | { |
8b110b48 AR |
100 | return id.print(os); |
101 | } | |
102 | ||
ff9d9458 | 103 | #endif /* SQUID_SRC_BASE_INSTANCEID_H */ |
f53969cc | 104 |