tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

cordz_handle.h (4079B)


      1 // Copyright 2019 The Abseil Authors.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //      https://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #ifndef ABSL_STRINGS_INTERNAL_CORDZ_HANDLE_H_
     16 #define ABSL_STRINGS_INTERNAL_CORDZ_HANDLE_H_
     17 
     18 #include <atomic>
     19 #include <vector>
     20 
     21 #include "absl/base/config.h"
     22 #include "absl/base/internal/raw_logging.h"
     23 
     24 namespace absl {
     25 ABSL_NAMESPACE_BEGIN
     26 namespace cord_internal {
     27 
     28 // This base class allows multiple types of object (CordzInfo and
     29 // CordzSampleToken) to exist simultaneously on the delete queue (pointed to by
     30 // global_dq_tail and traversed using dq_prev_ and dq_next_). The
     31 // delete queue guarantees that once a profiler creates a CordzSampleToken and
     32 // has gained visibility into a CordzInfo object, that CordzInfo object will not
     33 // be deleted prematurely. This allows the profiler to inspect all CordzInfo
     34 // objects that are alive without needing to hold a global lock.
     35 class ABSL_DLL CordzHandle {
     36 public:
     37  CordzHandle() : CordzHandle(false) {}
     38 
     39  bool is_snapshot() const { return is_snapshot_; }
     40 
     41  // Returns true if this instance is safe to be deleted because it is either a
     42  // snapshot, which is always safe to delete, or not included in the global
     43  // delete queue and thus not included in any snapshot.
     44  // Callers are responsible for making sure this instance can not be newly
     45  // discovered by other threads. For example, CordzInfo instances first de-list
     46  // themselves from the global CordzInfo list before determining if they are
     47  // safe to be deleted directly.
     48  // If SafeToDelete returns false, callers MUST use the Delete() method to
     49  // safely queue CordzHandle instances for deletion.
     50  bool SafeToDelete() const;
     51 
     52  // Deletes the provided instance, or puts it on the delete queue to be deleted
     53  // once there are no more sample tokens (snapshot) instances potentially
     54  // referencing the instance. `handle` should not be null.
     55  static void Delete(CordzHandle* handle);
     56 
     57  // Returns the current entries in the delete queue in LIFO order.
     58  static std::vector<const CordzHandle*> DiagnosticsGetDeleteQueue();
     59 
     60  // Returns true if the provided handle is nullptr or guarded by this handle.
     61  // Since the CordzSnapshot token is itself a CordzHandle, this method will
     62  // allow tests to check if that token is keeping an arbitrary CordzHandle
     63  // alive.
     64  bool DiagnosticsHandleIsSafeToInspect(const CordzHandle* handle) const;
     65 
     66  // Returns the current entries in the delete queue, in LIFO order, that are
     67  // protected by this. CordzHandle objects are only placed on the delete queue
     68  // after CordzHandle::Delete is called with them as an argument. Only
     69  // CordzHandle objects that are not also CordzSnapshot objects will be
     70  // included in the return vector. For each of the handles in the return
     71  // vector, the earliest that their memory can be freed is when this
     72  // CordzSnapshot object is deleted.
     73  std::vector<const CordzHandle*> DiagnosticsGetSafeToInspectDeletedHandles();
     74 
     75 protected:
     76  explicit CordzHandle(bool is_snapshot);
     77  virtual ~CordzHandle();
     78 
     79 private:
     80  const bool is_snapshot_;
     81 
     82  // dq_prev_ and dq_next_ require the global queue mutex to be held.
     83  // Unfortunately we can't use thread annotations such that the thread safety
     84  // analysis understands that queue_ and global_queue_ are one and the same.
     85  CordzHandle* dq_prev_  = nullptr;
     86  CordzHandle* dq_next_ = nullptr;
     87 };
     88 
     89 class CordzSnapshot : public CordzHandle {
     90 public:
     91  CordzSnapshot() : CordzHandle(true) {}
     92 };
     93 
     94 }  // namespace cord_internal
     95 ABSL_NAMESPACE_END
     96 }  // namespace absl
     97 
     98 #endif  // ABSL_STRINGS_INTERNAL_CORDZ_HANDLE_H_