]>
Commit | Line | Data |
---|---|---|
ebaabe74 | 1 | /* |
f70aedc4 | 2 | * Copyright (C) 1996-2021 The Squid Software Foundation and contributors |
ebaabe74 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 files for details. | |
7 | */ | |
8 | ||
9 | #ifndef SQUID_BASE_HERE_H | |
10 | #define SQUID_BASE_HERE_H | |
11 | ||
12 | #include <iosfwd> | |
13 | ||
14 | /// source code location of the caller | |
15 | #define Here() SourceLocation(__FUNCTION__, __FILE__, __LINE__) | |
16 | ||
17 | /// semi-uniquely identifies a source code location; stable across Squid runs | |
18 | typedef uint32_t SourceLocationId; | |
19 | ||
20 | /// returns a hash of a file name | |
21 | typedef SourceLocationId FileNameHasher(const char *fileName); | |
22 | ||
23 | /// a caching proxy for `hasher` results | |
24 | typedef SourceLocationId FileNameHashCacher(const char *fileName, FileNameHasher hasher); | |
25 | ||
26 | static FileNameHashCacher UnitFileNameHashCacher; | |
27 | ||
28 | /// a source code location that is cheap to create, copy, and store | |
29 | class SourceLocation | |
30 | { | |
31 | public: | |
32 | SourceLocation(const char *aContext, const char *aFileName, const int aLineNo): | |
33 | context(aContext), | |
34 | fileName(aFileName), | |
35 | lineNo(aLineNo), | |
36 | fileNameHashCacher(&UnitFileNameHashCacher) | |
37 | {} | |
38 | ||
39 | /// \returns our location identifier | |
40 | SourceLocationId id() const; | |
41 | ||
42 | /// describes location using a compact but human-friendly format | |
43 | std::ostream &print(std::ostream &os) const; | |
44 | ||
45 | const char *context; ///< line-independent location description | |
46 | const char *fileName; ///< source file name, often relative to build path | |
47 | int lineNo; ///< line number inside the source file name (if positive) | |
48 | ||
49 | private: | |
50 | SourceLocationId calculateId(FileNameHasher) const; | |
51 | FileNameHashCacher *fileNameHashCacher; | |
52 | }; | |
53 | ||
54 | inline std::ostream & | |
55 | operator <<(std::ostream &os, const SourceLocation &location) | |
56 | { | |
57 | return location.print(os); | |
58 | } | |
59 | ||
60 | /// SourceLocation::id() speed optimization hack: Caches `hasher` results. The | |
61 | /// cache capacity is one filename hash. Each translation unit gets one cache. | |
62 | static SourceLocationId | |
63 | UnitFileNameHashCacher(const char *fileName, FileNameHasher hasher) | |
64 | { | |
65 | static SourceLocationId cachedHash = 0; | |
66 | static const char *hashedFilename = 0; | |
67 | // Each file #included in a translation unit has its own __FILE__ value. | |
68 | // Keep the cache fresh (and the result correct). | |
69 | if (hashedFilename != fileName) { // cheap pointer comparison | |
70 | hashedFilename = fileName; | |
71 | cachedHash = hasher(fileName); | |
72 | } | |
73 | return cachedHash; | |
74 | } | |
75 | ||
76 | #endif | |
77 |