Commit 0fdb3281 authored by Peter Kasting's avatar Peter Kasting Committed by Commit Bot

Add CallbackList::AddUnsafe().

This is useful for callers who never want to cancel callbacks and can
guarantee the lifetime requirements.  For example, callbacks bound on
the same object that owns the CallbackList.

Bug: 1113007
Change-Id: I258d029360213a689bf888cca662ae56dec4cd74
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2337537
Commit-Queue: Peter Kasting <pkasting@chromium.org>
Auto-Submit: Peter Kasting <pkasting@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#795349}
parent 0b796d63
...@@ -143,6 +143,17 @@ class CallbackListBase { ...@@ -143,6 +143,17 @@ class CallbackListBase {
callbacks_.insert(callbacks_.end(), std::move(cb)))); callbacks_.insert(callbacks_.end(), std::move(cb))));
} }
// Registers |cb| for future notifications. Provides no way for the caller to
// cancel, so this is only safe for cases where the callback is guaranteed to
// live at least as long as this list (e.g. if it's bound on the same object
// that owns the list).
// TODO(pkasting): Attempt to use Add() instead and see if callers can relax
// other lifetime/ordering mechanisms as a result.
void AddUnsafe(CallbackType cb) {
DCHECK(!cb.is_null());
callbacks_.push_back(std::move(cb));
}
// Registers |removal_callback| to be run after elements are removed from the // Registers |removal_callback| to be run after elements are removed from the
// list of registered callbacks. // list of registered callbacks.
void set_removal_callback(const RepeatingClosure& removal_callback) { void set_removal_callback(const RepeatingClosure& removal_callback) {
......
...@@ -181,13 +181,14 @@ TEST(CallbackListTest, ArityTest) { ...@@ -181,13 +181,14 @@ TEST(CallbackListTest, ArityTest) {
// Sanity check that closures added to the list will be run, and those removed // Sanity check that closures added to the list will be run, and those removed
// from the list will not be run. // from the list will not be run.
TEST(CallbackListTest, BasicTest) { TEST(CallbackListTest, BasicTest) {
RepeatingClosureList cb_reg;
Listener a, b, c; Listener a, b, c;
RepeatingClosureList cb_reg;
std::unique_ptr<RepeatingClosureList::Subscription> a_subscription = std::unique_ptr<RepeatingClosureList::Subscription> a_subscription =
cb_reg.Add(BindRepeating(&Listener::IncrementTotal, Unretained(&a))); cb_reg.Add(BindRepeating(&Listener::IncrementTotal, Unretained(&a)));
std::unique_ptr<RepeatingClosureList::Subscription> b_subscription = std::unique_ptr<RepeatingClosureList::Subscription> b_subscription =
cb_reg.Add(BindRepeating(&Listener::IncrementTotal, Unretained(&b))); cb_reg.Add(BindRepeating(&Listener::IncrementTotal, Unretained(&b)));
cb_reg.AddUnsafe(BindRepeating(&Listener::IncrementTotal, Unretained(&c)));
EXPECT_TRUE(a_subscription.get()); EXPECT_TRUE(a_subscription.get());
EXPECT_TRUE(b_subscription.get()); EXPECT_TRUE(b_subscription.get());
...@@ -196,6 +197,7 @@ TEST(CallbackListTest, BasicTest) { ...@@ -196,6 +197,7 @@ TEST(CallbackListTest, BasicTest) {
EXPECT_EQ(1, a.total()); EXPECT_EQ(1, a.total());
EXPECT_EQ(1, b.total()); EXPECT_EQ(1, b.total());
EXPECT_EQ(1, c.total());
b_subscription.reset(); b_subscription.reset();
...@@ -206,7 +208,7 @@ TEST(CallbackListTest, BasicTest) { ...@@ -206,7 +208,7 @@ TEST(CallbackListTest, BasicTest) {
EXPECT_EQ(2, a.total()); EXPECT_EQ(2, a.total());
EXPECT_EQ(1, b.total()); EXPECT_EQ(1, b.total());
EXPECT_EQ(1, c.total()); EXPECT_EQ(3, c.total());
} }
// Similar to BasicTest but with OnceCallbacks instead of Repeating. // Similar to BasicTest but with OnceCallbacks instead of Repeating.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment