xref: /aosp_15_r20/external/cronet/base/supports_user_data.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_SUPPORTS_USER_DATA_H_
6*6777b538SAndroid Build Coastguard Worker #define BASE_SUPPORTS_USER_DATA_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <map>
9*6777b538SAndroid Build Coastguard Worker #include <memory>
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/memory/scoped_refptr.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/sequence_checker.h"
14*6777b538SAndroid Build Coastguard Worker #include "third_party/abseil-cpp/absl/container/flat_hash_map.h"
15*6777b538SAndroid Build Coastguard Worker 
16*6777b538SAndroid Build Coastguard Worker namespace base {
17*6777b538SAndroid Build Coastguard Worker 
18*6777b538SAndroid Build Coastguard Worker // This is a helper for classes that want to allow users to stash random data by
19*6777b538SAndroid Build Coastguard Worker // key. At destruction all the objects will be destructed.
20*6777b538SAndroid Build Coastguard Worker class BASE_EXPORT SupportsUserData {
21*6777b538SAndroid Build Coastguard Worker  public:
22*6777b538SAndroid Build Coastguard Worker   SupportsUserData();
23*6777b538SAndroid Build Coastguard Worker   SupportsUserData(SupportsUserData&&);
24*6777b538SAndroid Build Coastguard Worker   SupportsUserData& operator=(SupportsUserData&&);
25*6777b538SAndroid Build Coastguard Worker   SupportsUserData(const SupportsUserData&) = delete;
26*6777b538SAndroid Build Coastguard Worker   SupportsUserData& operator=(const SupportsUserData&) = delete;
27*6777b538SAndroid Build Coastguard Worker 
28*6777b538SAndroid Build Coastguard Worker   // Derive from this class and add your own data members to associate extra
29*6777b538SAndroid Build Coastguard Worker   // information with this object. Alternatively, add this as a public base
30*6777b538SAndroid Build Coastguard Worker   // class to any class with a virtual destructor.
31*6777b538SAndroid Build Coastguard Worker   class BASE_EXPORT Data {
32*6777b538SAndroid Build Coastguard Worker    public:
33*6777b538SAndroid Build Coastguard Worker     virtual ~Data() = default;
34*6777b538SAndroid Build Coastguard Worker 
35*6777b538SAndroid Build Coastguard Worker     // Returns a copy of |this|; null if copy is not supported.
36*6777b538SAndroid Build Coastguard Worker     virtual std::unique_ptr<Data> Clone();
37*6777b538SAndroid Build Coastguard Worker   };
38*6777b538SAndroid Build Coastguard Worker 
39*6777b538SAndroid Build Coastguard Worker   // The user data allows the clients to associate data with this object.
40*6777b538SAndroid Build Coastguard Worker   // |key| must not be null--that value is too vulnerable for collision.
41*6777b538SAndroid Build Coastguard Worker   // NOTE: SetUserData() with an empty unique_ptr behaves the same as
42*6777b538SAndroid Build Coastguard Worker   // RemoveUserData().
43*6777b538SAndroid Build Coastguard Worker   Data* GetUserData(const void* key) const;
44*6777b538SAndroid Build Coastguard Worker   [[nodiscard]] std::unique_ptr<Data> TakeUserData(const void* key);
45*6777b538SAndroid Build Coastguard Worker   void SetUserData(const void* key, std::unique_ptr<Data> data);
46*6777b538SAndroid Build Coastguard Worker   void RemoveUserData(const void* key);
47*6777b538SAndroid Build Coastguard Worker 
48*6777b538SAndroid Build Coastguard Worker   // Adds all data from |other|, that is clonable, to |this|. That is, this
49*6777b538SAndroid Build Coastguard Worker   // iterates over the data in |other|, and any data that returns non-null from
50*6777b538SAndroid Build Coastguard Worker   // Clone() is added to |this|.
51*6777b538SAndroid Build Coastguard Worker   void CloneDataFrom(const SupportsUserData& other);
52*6777b538SAndroid Build Coastguard Worker 
53*6777b538SAndroid Build Coastguard Worker   // SupportsUserData is not thread-safe, and on debug build will assert it is
54*6777b538SAndroid Build Coastguard Worker   // only used on one execution sequence. Calling this method allows the caller
55*6777b538SAndroid Build Coastguard Worker   // to hand the SupportsUserData instance across execution sequences. Use only
56*6777b538SAndroid Build Coastguard Worker   // if you are taking full control of the synchronization of that hand over.
57*6777b538SAndroid Build Coastguard Worker   void DetachFromSequence();
58*6777b538SAndroid Build Coastguard Worker 
59*6777b538SAndroid Build Coastguard Worker  protected:
60*6777b538SAndroid Build Coastguard Worker   virtual ~SupportsUserData();
61*6777b538SAndroid Build Coastguard Worker 
62*6777b538SAndroid Build Coastguard Worker   // Clear all user data from this object. This can be used if the subclass
63*6777b538SAndroid Build Coastguard Worker   // needs to provide reset functionality.
64*6777b538SAndroid Build Coastguard Worker   void ClearAllUserData();
65*6777b538SAndroid Build Coastguard Worker 
66*6777b538SAndroid Build Coastguard Worker  private:
67*6777b538SAndroid Build Coastguard Worker   // Externally-defined data accessible by key.
68*6777b538SAndroid Build Coastguard Worker   absl::flat_hash_map<const void*, std::unique_ptr<Data>> user_data_;
69*6777b538SAndroid Build Coastguard Worker   bool in_destructor_ = false;
70*6777b538SAndroid Build Coastguard Worker   // Guards usage of |user_data_|
71*6777b538SAndroid Build Coastguard Worker   SEQUENCE_CHECKER(sequence_checker_);
72*6777b538SAndroid Build Coastguard Worker };
73*6777b538SAndroid Build Coastguard Worker 
74*6777b538SAndroid Build Coastguard Worker // Adapter class that releases a refcounted object when the
75*6777b538SAndroid Build Coastguard Worker // SupportsUserData::Data object is deleted.
76*6777b538SAndroid Build Coastguard Worker template <typename T>
77*6777b538SAndroid Build Coastguard Worker class UserDataAdapter : public SupportsUserData::Data {
78*6777b538SAndroid Build Coastguard Worker  public:
Get(const SupportsUserData * supports_user_data,const void * key)79*6777b538SAndroid Build Coastguard Worker   static T* Get(const SupportsUserData* supports_user_data, const void* key) {
80*6777b538SAndroid Build Coastguard Worker     UserDataAdapter* data =
81*6777b538SAndroid Build Coastguard Worker       static_cast<UserDataAdapter*>(supports_user_data->GetUserData(key));
82*6777b538SAndroid Build Coastguard Worker     return data ? static_cast<T*>(data->object_.get()) : nullptr;
83*6777b538SAndroid Build Coastguard Worker   }
84*6777b538SAndroid Build Coastguard Worker 
UserDataAdapter(T * object)85*6777b538SAndroid Build Coastguard Worker   explicit UserDataAdapter(T* object) : object_(object) {}
86*6777b538SAndroid Build Coastguard Worker   UserDataAdapter(const UserDataAdapter&) = delete;
87*6777b538SAndroid Build Coastguard Worker   UserDataAdapter& operator=(const UserDataAdapter&) = delete;
88*6777b538SAndroid Build Coastguard Worker   ~UserDataAdapter() override = default;
89*6777b538SAndroid Build Coastguard Worker 
release()90*6777b538SAndroid Build Coastguard Worker   T* release() { return object_.release(); }
91*6777b538SAndroid Build Coastguard Worker 
92*6777b538SAndroid Build Coastguard Worker  private:
93*6777b538SAndroid Build Coastguard Worker   scoped_refptr<T> const object_;
94*6777b538SAndroid Build Coastguard Worker };
95*6777b538SAndroid Build Coastguard Worker 
96*6777b538SAndroid Build Coastguard Worker }  // namespace base
97*6777b538SAndroid Build Coastguard Worker 
98*6777b538SAndroid Build Coastguard Worker #endif  // BASE_SUPPORTS_USER_DATA_H_
99