diff options
Diffstat (limited to 'chromium/base/callback_list.h')
-rw-r--r-- | chromium/base/callback_list.h | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/chromium/base/callback_list.h b/chromium/base/callback_list.h index d12a1e95baa..5b911fd4867 100644 --- a/chromium/base/callback_list.h +++ b/chromium/base/callback_list.h @@ -89,10 +89,13 @@ class CallbackListBase { } ~Subscription() { - if (list_->active_iterator_count_) + if (list_->active_iterator_count_) { iter_->Reset(); - else + } else { list_->callbacks_.erase(iter_); + if (!list_->removal_callback_.is_null()) + list_->removal_callback_.Run(); + } } private: @@ -111,6 +114,18 @@ class CallbackListBase { new Subscription(this, callbacks_.insert(callbacks_.end(), cb))); } + // Sets a callback which will be run when a subscription list is changed. + void set_removal_callback(const Closure& callback) { + removal_callback_ = callback; + } + + // Returns true if there are no subscriptions. This is only valid to call when + // not looping through the list. + bool empty() { + DCHECK_EQ(0, active_iterator_count_); + return callbacks_.empty(); + } + protected: // An iterator class that can be used to access the list of callbacks. class Iterator { @@ -167,17 +182,24 @@ class CallbackListBase { // iteration. void Compact() { typename std::list<CallbackType>::iterator it = callbacks_.begin(); + bool updated = false; while (it != callbacks_.end()) { - if ((*it).is_null()) + if ((*it).is_null()) { + updated = true; it = callbacks_.erase(it); - else + } else { ++it; + } + + if (updated && !removal_callback_.is_null()) + removal_callback_.Run(); } } private: std::list<CallbackType> callbacks_; int active_iterator_count_; + Closure removal_callback_; DISALLOW_COPY_AND_ASSIGN(CallbackListBase); }; |