[email protected] | ea8e181 | 2012-02-15 22:07:34 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 | // Use of this source code is governed by a BSD-style license that can be | ||||
3 | // found in the LICENSE file. | ||||
4 | |||||
5 | #ifndef BASE_SUPPORTS_USER_DATA_H_ | ||||
6 | #define BASE_SUPPORTS_USER_DATA_H_ | ||||
7 | |||||
8 | #include <map> | ||||
9 | |||||
10 | #include "base/base_export.h" | ||||
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 11 | #include "base/macros.h" |
[email protected] | ea8e181 | 2012-02-15 22:07:34 | [diff] [blame] | 12 | #include "base/memory/linked_ptr.h" |
[email protected] | 314c3e2 | 2012-02-21 03:57:42 | [diff] [blame] | 13 | #include "base/memory/ref_counted.h" |
[email protected] | 7d2e5f762 | 2012-09-10 19:18:53 | [diff] [blame] | 14 | #include "base/threading/thread_checker.h" |
[email protected] | ea8e181 | 2012-02-15 22:07:34 | [diff] [blame] | 15 | |
16 | namespace base { | ||||
17 | |||||
18 | // This is a helper for classes that want to allow users to stash random data by | ||||
19 | // key. At destruction all the objects will be destructed. | ||||
20 | class BASE_EXPORT SupportsUserData { | ||||
21 | public: | ||||
22 | SupportsUserData(); | ||||
[email protected] | ea8e181 | 2012-02-15 22:07:34 | [diff] [blame] | 23 | |
24 | // Derive from this class and add your own data members to associate extra | ||||
[email protected] | 5b9f0b5 | 2012-08-20 22:58:21 | [diff] [blame] | 25 | // information with this object. Alternatively, add this as a public base |
26 | // class to any class with a virtual destructor. | ||||
[email protected] | ea8e181 | 2012-02-15 22:07:34 | [diff] [blame] | 27 | class BASE_EXPORT Data { |
28 | public: | ||||
29 | virtual ~Data() {} | ||||
30 | }; | ||||
31 | |||||
32 | // The user data allows the clients to associate data with this object. | ||||
33 | // Multiple user data values can be stored under different keys. | ||||
34 | // This object will TAKE OWNERSHIP of the given data pointer, and will | ||||
35 | // delete the object if it is changed or the object is destroyed. | ||||
36 | Data* GetUserData(const void* key) const; | ||||
37 | void SetUserData(const void* key, Data* data); | ||||
[email protected] | 27ee16f | 2012-08-12 02:25:13 | [diff] [blame] | 38 | void RemoveUserData(const void* key); |
[email protected] | ea8e181 | 2012-02-15 22:07:34 | [diff] [blame] | 39 | |
[email protected] | 7d2e5f762 | 2012-09-10 19:18:53 | [diff] [blame] | 40 | // SupportsUserData is not thread-safe, and on debug build will assert it is |
41 | // only used on one thread. Calling this method allows the caller to hand | ||||
42 | // the SupportsUserData instance across threads. Use only if you are taking | ||||
43 | // full control of the synchronization of that hand over. | ||||
44 | void DetachUserDataThread(); | ||||
45 | |||||
[email protected] | cb93248 | 2012-06-26 06:23:00 | [diff] [blame] | 46 | protected: |
47 | virtual ~SupportsUserData(); | ||||
48 | |||||
[email protected] | ea8e181 | 2012-02-15 22:07:34 | [diff] [blame] | 49 | private: |
50 | typedef std::map<const void*, linked_ptr<Data> > DataMap; | ||||
51 | |||||
[email protected] | 5b9f0b5 | 2012-08-20 22:58:21 | [diff] [blame] | 52 | // Externally-defined data accessible by key. |
[email protected] | ea8e181 | 2012-02-15 22:07:34 | [diff] [blame] | 53 | DataMap user_data_; |
[email protected] | 7d2e5f762 | 2012-09-10 19:18:53 | [diff] [blame] | 54 | // Guards usage of |user_data_| |
55 | ThreadChecker thread_checker_; | ||||
[email protected] | ea8e181 | 2012-02-15 22:07:34 | [diff] [blame] | 56 | |
57 | DISALLOW_COPY_AND_ASSIGN(SupportsUserData); | ||||
58 | }; | ||||
59 | |||||
[email protected] | 314c3e2 | 2012-02-21 03:57:42 | [diff] [blame] | 60 | // Adapter class that releases a refcounted object when the |
61 | // SupportsUserData::Data object is deleted. | ||||
62 | template <typename T> | ||||
63 | class UserDataAdapter : public base::SupportsUserData::Data { | ||||
64 | public: | ||||
horo | d556043 | 2014-12-12 06:20:13 | [diff] [blame] | 65 | static T* Get(const SupportsUserData* supports_user_data, const void* key) { |
[email protected] | 5537099 | 2012-10-08 21:08:54 | [diff] [blame] | 66 | UserDataAdapter* data = |
[email protected] | 314c3e2 | 2012-02-21 03:57:42 | [diff] [blame] | 67 | static_cast<UserDataAdapter*>(supports_user_data->GetUserData(key)); |
[email protected] | 5537099 | 2012-10-08 21:08:54 | [diff] [blame] | 68 | return data ? static_cast<T*>(data->object_.get()) : NULL; |
[email protected] | 314c3e2 | 2012-02-21 03:57:42 | [diff] [blame] | 69 | } |
70 | |||||
71 | UserDataAdapter(T* object) : object_(object) {} | ||||
[email protected] | c1fff07 | 2012-02-24 23:38:12 | [diff] [blame] | 72 | T* release() { return object_.release(); } |
[email protected] | 314c3e2 | 2012-02-21 03:57:42 | [diff] [blame] | 73 | |
74 | private: | ||||
75 | scoped_refptr<T> object_; | ||||
76 | |||||
77 | DISALLOW_COPY_AND_ASSIGN(UserDataAdapter); | ||||
78 | }; | ||||
79 | |||||
[email protected] | ea8e181 | 2012-02-15 22:07:34 | [diff] [blame] | 80 | } // namespace base |
81 | |||||
82 | #endif // BASE_SUPPORTS_USER_DATA_H_ |