|
|
|||
File indexing completed on 2025-12-16 09:41:00
0001 // Copyright 2019 The Abseil Authors. 0002 // 0003 // Licensed under the Apache License, Version 2.0 (the "License"); 0004 // you may not use this file except in compliance with the License. 0005 // You may obtain a copy of the License at 0006 // 0007 // https://www.apache.org/licenses/LICENSE-2.0 0008 // 0009 // Unless required by applicable law or agreed to in writing, software 0010 // distributed under the License is distributed on an "AS IS" BASIS, 0011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 0012 // See the License for the specific language governing permissions and 0013 // limitations under the License. 0014 0015 #ifndef ABSL_STRINGS_INTERNAL_CORDZ_HANDLE_H_ 0016 #define ABSL_STRINGS_INTERNAL_CORDZ_HANDLE_H_ 0017 0018 #include <atomic> 0019 #include <vector> 0020 0021 #include "absl/base/config.h" 0022 #include "absl/base/internal/raw_logging.h" 0023 0024 namespace absl { 0025 ABSL_NAMESPACE_BEGIN 0026 namespace cord_internal { 0027 0028 // This base class allows multiple types of object (CordzInfo and 0029 // CordzSampleToken) to exist simultaneously on the delete queue (pointed to by 0030 // global_dq_tail and traversed using dq_prev_ and dq_next_). The 0031 // delete queue guarantees that once a profiler creates a CordzSampleToken and 0032 // has gained visibility into a CordzInfo object, that CordzInfo object will not 0033 // be deleted prematurely. This allows the profiler to inspect all CordzInfo 0034 // objects that are alive without needing to hold a global lock. 0035 class ABSL_DLL CordzHandle { 0036 public: 0037 CordzHandle() : CordzHandle(false) {} 0038 0039 bool is_snapshot() const { return is_snapshot_; } 0040 0041 // Returns true if this instance is safe to be deleted because it is either a 0042 // snapshot, which is always safe to delete, or not included in the global 0043 // delete queue and thus not included in any snapshot. 0044 // Callers are responsible for making sure this instance can not be newly 0045 // discovered by other threads. For example, CordzInfo instances first de-list 0046 // themselves from the global CordzInfo list before determining if they are 0047 // safe to be deleted directly. 0048 // If SafeToDelete returns false, callers MUST use the Delete() method to 0049 // safely queue CordzHandle instances for deletion. 0050 bool SafeToDelete() const; 0051 0052 // Deletes the provided instance, or puts it on the delete queue to be deleted 0053 // once there are no more sample tokens (snapshot) instances potentially 0054 // referencing the instance. `handle` should not be null. 0055 static void Delete(CordzHandle* handle); 0056 0057 // Returns the current entries in the delete queue in LIFO order. 0058 static std::vector<const CordzHandle*> DiagnosticsGetDeleteQueue(); 0059 0060 // Returns true if the provided handle is nullptr or guarded by this handle. 0061 // Since the CordzSnapshot token is itself a CordzHandle, this method will 0062 // allow tests to check if that token is keeping an arbitrary CordzHandle 0063 // alive. 0064 bool DiagnosticsHandleIsSafeToInspect(const CordzHandle* handle) const; 0065 0066 // Returns the current entries in the delete queue, in LIFO order, that are 0067 // protected by this. CordzHandle objects are only placed on the delete queue 0068 // after CordzHandle::Delete is called with them as an argument. Only 0069 // CordzHandle objects that are not also CordzSnapshot objects will be 0070 // included in the return vector. For each of the handles in the return 0071 // vector, the earliest that their memory can be freed is when this 0072 // CordzSnapshot object is deleted. 0073 std::vector<const CordzHandle*> DiagnosticsGetSafeToInspectDeletedHandles(); 0074 0075 protected: 0076 explicit CordzHandle(bool is_snapshot); 0077 virtual ~CordzHandle(); 0078 0079 private: 0080 const bool is_snapshot_; 0081 0082 // dq_prev_ and dq_next_ require the global queue mutex to be held. 0083 // Unfortunately we can't use thread annotations such that the thread safety 0084 // analysis understands that queue_ and global_queue_ are one and the same. 0085 CordzHandle* dq_prev_ = nullptr; 0086 CordzHandle* dq_next_ = nullptr; 0087 }; 0088 0089 class CordzSnapshot : public CordzHandle { 0090 public: 0091 CordzSnapshot() : CordzHandle(true) {} 0092 }; 0093 0094 } // namespace cord_internal 0095 ABSL_NAMESPACE_END 0096 } // namespace absl 0097 0098 #endif // ABSL_STRINGS_INTERNAL_CORDZ_HANDLE_H_
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|