Index: chrome/common/deprecated/event_sys-inl.h |
diff --git a/chrome/common/deprecated/event_sys-inl.h b/chrome/common/deprecated/event_sys-inl.h |
deleted file mode 100644 |
index c92de6204caabb2855362da64bd3edbd49bf2b4c..0000000000000000000000000000000000000000 |
--- a/chrome/common/deprecated/event_sys-inl.h |
+++ /dev/null |
@@ -1,342 +0,0 @@ |
-// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#ifndef CHROME_COMMON_DEPRECATED_EVENT_SYS_INL_H_ |
-#define CHROME_COMMON_DEPRECATED_EVENT_SYS_INL_H_ |
-#pragma once |
- |
-#include <map> |
- |
-#include "base/basictypes.h" |
-#include "base/logging.h" |
-#include "base/message_loop.h" |
-#include "base/port.h" |
-#include "base/synchronization/condition_variable.h" |
-#include "base/synchronization/lock.h" |
-#include "chrome/common/deprecated/event_sys.h" |
- |
-// How to use Channels: |
- |
-// 0. Assume Bob is the name of the class from which you want to broadcast |
-// events. |
-// 1. Choose an EventType. This could be an Enum or something more complicated. |
-// 2. Create an EventTraits class for your EventType. It must have |
-// two members: |
-// |
-// typedef x EventType; |
-// static bool IsChannelShutdownEvent(const EventType& event); |
-// |
-// 3. Add an EventChannel<MyEventTraits>* instance and event_channel() const; |
-// accessor to Bob. |
-// Delete the channel ordinarily in Bob's destructor, or whenever you want. |
-// 4. To broadcast events, call bob->event_channel()->NotifyListeners(event). |
-// 5. Only call NotifyListeners from a single thread at a time. |
- |
-// How to use Listeners/Hookups: |
- |
-// 0. Assume you want a class called Lisa to listen to events from Bob. |
-// 1. Create an event handler method in Lisa. Its single argument should be of |
-// your event type. |
-// 2. Add a EventListenerHookup* hookup_ member to Lisa. |
-// 3. Initialize the hookup by calling: |
-// |
-// hookup_ = NewEventListenerHookup(bob->event_channel(), |
-// this, |
-// &Lisa::HandleEvent); |
-// |
-// 4. Delete hookup_ in Lisa's destructor, or anytime sooner to stop receiving |
-// events. |
- |
-// An Event Channel is a source, or broadcaster of events. Listeners subscribe |
-// by calling the AddListener() method. The owner of the channel calls the |
-// NotifyListeners() method. |
-// |
-// Don't inherit from this class. Just make an event_channel member and an |
-// event_channel() accessor. |
- |
-// No reason why CallbackWaiters has to be templatized. |
-class CallbackWaiters { |
- public: |
- CallbackWaiters() : waiter_count_(0), |
- callback_done_(false), |
- condvar_(&mutex_) { |
- } |
- ~CallbackWaiters() { |
- DCHECK_EQ(0, waiter_count_); |
- } |
- void WaitForCallbackToComplete(base::Lock* listeners_mutex) { |
- { |
- base::AutoLock lock(mutex_); |
- waiter_count_ += 1; |
- listeners_mutex->Release(); |
- while (!callback_done_) |
- condvar_.Wait(); |
- waiter_count_ -= 1; |
- if (0 != waiter_count_) |
- return; |
- } |
- delete this; |
- } |
- |
- void Signal() { |
- base::AutoLock lock(mutex_); |
- callback_done_ = true; |
- condvar_.Broadcast(); |
- } |
- |
- protected: |
- int waiter_count_; |
- bool callback_done_; |
- base::Lock mutex_; |
- base::ConditionVariable condvar_; |
-}; |
- |
-template <typename EventTraitsType, typename NotifyLock, |
- typename ScopedNotifyLocker> |
-class EventChannel { |
- public: |
- typedef EventTraitsType EventTraits; |
- typedef typename EventTraits::EventType EventType; |
- typedef EventListener<EventType> Listener; |
- |
- protected: |
- typedef std::map<Listener*, bool> Listeners; |
- |
- public: |
- // The shutdown event gets send in the EventChannel's destructor. |
- explicit EventChannel(const EventType& shutdown_event) |
- : current_listener_callback_(NULL), |
- current_listener_callback_message_loop_(NULL), |
- callback_waiters_(NULL), |
- shutdown_event_(shutdown_event) { |
- } |
- |
- ~EventChannel() { |
- // Tell all the listeners that the channel is being deleted. |
- NotifyListeners(shutdown_event_); |
- |
- // Make sure all the listeners have been disconnected. Otherwise, they |
- // will try to call RemoveListener() at a later date. |
-#if defined(DEBUG) |
- base::AutoLock lock(listeners_mutex_); |
- for (typename Listeners::iterator i = listeners_.begin(); |
- i != listeners_.end(); ++i) { |
- DCHECK(i->second) << "Listener not disconnected"; |
- } |
-#endif |
- } |
- |
- // Never call this twice for the same listener. |
- // |
- // Thread safe. |
- void AddListener(Listener* listener) { |
- base::AutoLock lock(listeners_mutex_); |
- typename Listeners::iterator found = listeners_.find(listener); |
- if (found == listeners_.end()) { |
- listeners_.insert(std::make_pair(listener, |
- false)); // Not dead yet. |
- } else { |
- DCHECK(found->second) << "Attempted to add the same listener twice."; |
- found->second = false; // Not dead yet. |
- } |
- } |
- |
- // If listener's callback is currently executing, this method waits until the |
- // callback completes before returning. |
- // |
- // Thread safe. |
- void RemoveListener(Listener* listener) { |
- bool wait = false; |
- listeners_mutex_.Acquire(); |
- typename Listeners::iterator found = listeners_.find(listener); |
- if (found != listeners_.end()) { |
- found->second = true; // Mark as dead. |
- wait = (found->first == current_listener_callback_ && |
- (MessageLoop::current() != current_listener_callback_message_loop_)); |
- } |
- if (!wait) { |
- listeners_mutex_.Release(); |
- return; |
- } |
- if (NULL == callback_waiters_) |
- callback_waiters_ = new CallbackWaiters; |
- callback_waiters_->WaitForCallbackToComplete(&listeners_mutex_); |
- } |
- |
- // Blocks until all listeners have been notified. |
- // |
- // NOT thread safe. Must only be called by one thread at a time. |
- void NotifyListeners(const EventType& event) { |
- ScopedNotifyLocker lock_notify(notify_lock_); |
- listeners_mutex_.Acquire(); |
- DCHECK(NULL == current_listener_callback_); |
- current_listener_callback_message_loop_ = MessageLoop::current(); |
- typename Listeners::iterator i = listeners_.begin(); |
- while (i != listeners_.end()) { |
- if (i->second) { // Clean out dead listeners |
- listeners_.erase(i++); |
- continue; |
- } |
- current_listener_callback_ = i->first; |
- listeners_mutex_.Release(); |
- |
- i->first->HandleEvent(event); |
- |
- listeners_mutex_.Acquire(); |
- current_listener_callback_ = NULL; |
- if (NULL != callback_waiters_) { |
- callback_waiters_->Signal(); |
- callback_waiters_ = NULL; |
- } |
- |
- ++i; |
- } |
- listeners_mutex_.Release(); |
- } |
- |
- // A map iterator remains valid until the element it points to gets removed |
- // from the map, so a map is perfect for our needs. |
- // |
- // Map value is a bool, true means the Listener is dead. |
- Listeners listeners_; |
- // NULL means no callback is currently being called. |
- Listener* current_listener_callback_; |
- // Only valid when current_listener is not NULL. |
- // The thread on which the callback is executing. |
- MessageLoop* current_listener_callback_message_loop_; |
- // Win32 Event that is usually NULL. Only created when another thread calls |
- // Remove while in callback. Owned and closed by the thread calling Remove(). |
- CallbackWaiters* callback_waiters_; |
- |
- base::Lock listeners_mutex_; // Protects all members above. |
- const EventType shutdown_event_; |
- NotifyLock notify_lock_; |
- |
- DISALLOW_COPY_AND_ASSIGN(EventChannel); |
-}; |
- |
-// An EventListenerHookup hooks up a method in your class to an EventChannel. |
-// Deleting the hookup disconnects from the EventChannel. |
-// |
-// Contains complexity of inheriting from Listener class and managing lifetimes. |
-// |
-// Create using NewEventListenerHookup() to avoid explicit template arguments. |
-class EventListenerHookup { |
- public: |
- virtual ~EventListenerHookup() { } |
-}; |
- |
-template <typename EventChannel, typename EventTraits, |
- class Derived> |
-class EventListenerHookupImpl : public EventListenerHookup, |
-public EventListener<typename EventTraits::EventType> { |
- public: |
- explicit EventListenerHookupImpl(EventChannel* channel) |
- : channel_(channel), deleted_(NULL) { |
- channel->AddListener(this); |
- connected_ = true; |
- } |
- |
- ~EventListenerHookupImpl() { |
- if (NULL != deleted_) |
- *deleted_ = true; |
- if (connected_) |
- channel_->RemoveListener(this); |
- } |
- |
- typedef typename EventTraits::EventType EventType; |
- virtual void HandleEvent(const EventType& event) { |
- DCHECK(connected_); |
- bool deleted = false; |
- deleted_ = &deleted; |
- static_cast<Derived*>(this)->Callback(event); |
- if (deleted) // The callback (legally) deleted this. |
- return; // The only safe thing to do. |
- deleted_ = NULL; |
- if (EventTraits::IsChannelShutdownEvent(event)) { |
- channel_->RemoveListener(this); |
- connected_ = false; |
- } |
- } |
- |
- protected: |
- EventChannel* const channel_; |
- bool connected_; |
- bool* deleted_; // Allows the handler to delete the hookup. |
-}; |
- |
-// SimpleHookup just passes the event to the callback message. |
-template <typename EventChannel, typename EventTraits, |
- typename CallbackObject, typename CallbackMethod> |
-class SimpleHookup |
- : public EventListenerHookupImpl<EventChannel, EventTraits, |
- SimpleHookup<EventChannel, |
- EventTraits, |
- CallbackObject, |
- CallbackMethod> > { |
- public: |
- SimpleHookup(EventChannel* channel, CallbackObject* cbobject, |
- CallbackMethod cbmethod) |
- : EventListenerHookupImpl<EventChannel, EventTraits, |
- SimpleHookup>(channel), cbobject_(cbobject), |
- cbmethod_(cbmethod) { } |
- |
- typedef typename EventTraits::EventType EventType; |
- void Callback(const EventType& event) { |
- (cbobject_->*cbmethod_)(event); |
- } |
- CallbackObject* const cbobject_; |
- CallbackMethod const cbmethod_; |
-}; |
- |
-// ArgHookup also passes an additional arg to the callback method. |
-template <typename EventChannel, typename EventTraits, |
- typename CallbackObject, typename CallbackMethod, |
- typename CallbackArg0> |
-class ArgHookup |
- : public EventListenerHookupImpl<EventChannel, EventTraits, |
- ArgHookup<EventChannel, EventTraits, |
- CallbackObject, |
- CallbackMethod, |
- CallbackArg0> > { |
- public: |
- ArgHookup(EventChannel* channel, CallbackObject* cbobject, |
- CallbackMethod cbmethod, CallbackArg0 arg0) |
- : EventListenerHookupImpl<EventChannel, EventTraits, |
- ArgHookup>(channel), cbobject_(cbobject), |
- cbmethod_(cbmethod), arg0_(arg0) { } |
- |
- typedef typename EventTraits::EventType EventType; |
- void Callback(const EventType& event) { |
- (cbobject_->*cbmethod_)(arg0_, event); |
- } |
- CallbackObject* const cbobject_; |
- CallbackMethod const cbmethod_; |
- CallbackArg0 const arg0_; |
-}; |
- |
- |
-template <typename EventChannel, typename CallbackObject, |
- typename CallbackMethod> |
-EventListenerHookup* NewEventListenerHookup(EventChannel* channel, |
- CallbackObject* cbobject, |
- CallbackMethod cbmethod) { |
- return new SimpleHookup<EventChannel, |
- typename EventChannel::EventTraits, |
- CallbackObject, CallbackMethod>(channel, cbobject, cbmethod); |
-} |
- |
-template <typename EventChannel, typename CallbackObject, |
- typename CallbackMethod, typename CallbackArg0> |
-EventListenerHookup* NewEventListenerHookup(EventChannel* channel, |
- CallbackObject* cbobject, |
- CallbackMethod cbmethod, |
- CallbackArg0 arg0) { |
- return new ArgHookup<EventChannel, |
- typename EventChannel::EventTraits, |
- CallbackObject, CallbackMethod, CallbackArg0>(channel, cbobject, |
- cbmethod, arg0); |
-} |
- |
-#endif // CHROME_COMMON_DEPRECATED_EVENT_SYS_INL_H_ |