OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CHROME_BROWSER_SYNC_UTIL_CHANNEL_H_ | 5 #ifndef CHROME_BROWSER_SYNC_UTIL_CHANNEL_H_ |
6 #define CHROME_BROWSER_SYNC_UTIL_CHANNEL_H_ | 6 #define CHROME_BROWSER_SYNC_UTIL_CHANNEL_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 /////////////////////////////////////////////////////////////////////////////// | 9 /////////////////////////////////////////////////////////////////////////////// |
10 // | 10 // |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 // channel_.Notify(event); | 43 // channel_.Notify(event); |
44 // } | 44 // } |
45 // | 45 // |
46 // private: | 46 // private: |
47 // Channel<FooEvent> channel_; | 47 // Channel<FooEvent> channel_; |
48 // }; | 48 // }; |
49 // | 49 // |
50 // | 50 // |
51 /////////////////////////////////////////////////////////////////////////////// | 51 /////////////////////////////////////////////////////////////////////////////// |
52 | 52 |
53 #include "base/lock.h" | |
54 #include "base/observer_list.h" | 53 #include "base/observer_list.h" |
| 54 #include "base/synchronization/lock.h" |
55 #include "base/threading/platform_thread.h" | 55 #include "base/threading/platform_thread.h" |
56 | 56 |
57 namespace browser_sync { | 57 namespace browser_sync { |
58 | 58 |
59 template <typename EventType> | 59 template <typename EventType> |
60 class Channel; | 60 class Channel; |
61 | 61 |
62 class EventHandler { | 62 class EventHandler { |
63 }; | 63 }; |
64 | 64 |
(...skipping 26 matching lines...) Expand all Loading... |
91 | 91 |
92 template <typename EventType> | 92 template <typename EventType> |
93 class Channel { | 93 class Channel { |
94 public: | 94 public: |
95 typedef ObserverListBase<EventHandler> ChannelObserverList; | 95 typedef ObserverListBase<EventHandler> ChannelObserverList; |
96 | 96 |
97 Channel() : locking_thread_(0) {} | 97 Channel() : locking_thread_(0) {} |
98 | 98 |
99 ChannelHookup<EventType>* AddObserver( | 99 ChannelHookup<EventType>* AddObserver( |
100 ChannelEventHandler<EventType>* observer) { | 100 ChannelEventHandler<EventType>* observer) { |
101 AutoLock scoped_lock(event_handlers_mutex_); | 101 base::AutoLock scoped_lock(event_handlers_mutex_); |
102 event_handlers_.AddObserver(observer); | 102 event_handlers_.AddObserver(observer); |
103 return new ChannelHookup<EventType>(this, observer); | 103 return new ChannelHookup<EventType>(this, observer); |
104 } | 104 } |
105 | 105 |
106 void RemoveObserver(ChannelEventHandler<EventType>* observer) { | 106 void RemoveObserver(ChannelEventHandler<EventType>* observer) { |
107 // This can be called in response to a notification, so we may already have | 107 // This can be called in response to a notification, so we may already have |
108 // locked this channel on this thread. | 108 // locked this channel on this thread. |
109 bool need_lock = (locking_thread_ != base::PlatformThread::CurrentId()); | 109 bool need_lock = (locking_thread_ != base::PlatformThread::CurrentId()); |
110 if (need_lock) | 110 if (need_lock) |
111 event_handlers_mutex_.Acquire(); | 111 event_handlers_mutex_.Acquire(); |
112 | 112 |
113 event_handlers_mutex_.AssertAcquired(); | 113 event_handlers_mutex_.AssertAcquired(); |
114 event_handlers_.RemoveObserver(observer); | 114 event_handlers_.RemoveObserver(observer); |
115 if (need_lock) | 115 if (need_lock) |
116 event_handlers_mutex_.Release(); | 116 event_handlers_mutex_.Release(); |
117 } | 117 } |
118 | 118 |
119 void Notify(const EventType& event) { | 119 void Notify(const EventType& event) { |
120 AutoLock scoped_lock(event_handlers_mutex_); | 120 base::AutoLock scoped_lock(event_handlers_mutex_); |
121 | 121 |
122 // This may result in an observer trying to remove itself, so keep track | 122 // This may result in an observer trying to remove itself, so keep track |
123 // of the thread we're locked on. | 123 // of the thread we're locked on. |
124 locking_thread_ = base::PlatformThread::CurrentId(); | 124 locking_thread_ = base::PlatformThread::CurrentId(); |
125 | 125 |
126 ChannelObserverList::Iterator it(event_handlers_); | 126 ChannelObserverList::Iterator it(event_handlers_); |
127 EventHandler* obs; | 127 EventHandler* obs; |
128 while ((obs = it.GetNext()) != NULL) { | 128 while ((obs = it.GetNext()) != NULL) { |
129 static_cast<ChannelEventHandler<EventType>* >(obs)-> | 129 static_cast<ChannelEventHandler<EventType>* >(obs)-> |
130 HandleChannelEvent(event); | 130 HandleChannelEvent(event); |
131 } | 131 } |
132 | 132 |
133 // Set back to an invalid thread id. | 133 // Set back to an invalid thread id. |
134 locking_thread_ = 0; | 134 locking_thread_ = 0; |
135 } | 135 } |
136 | 136 |
137 private: | 137 private: |
138 Lock event_handlers_mutex_; | 138 base::Lock event_handlers_mutex_; |
139 base::PlatformThreadId locking_thread_; | 139 base::PlatformThreadId locking_thread_; |
140 ObserverList<EventHandler> event_handlers_; | 140 ObserverList<EventHandler> event_handlers_; |
141 }; | 141 }; |
142 | 142 |
143 } // namespace browser_sync | 143 } // namespace browser_sync |
144 | 144 |
145 #endif // CHROME_BROWSER_SYNC_UTIL_CHANNEL_H_ | 145 #endif // CHROME_BROWSER_SYNC_UTIL_CHANNEL_H_ |
OLD | NEW |