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