Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(503)

Unified Diff: webrtc/base/sigslot_unittest.cc

Issue 2846593005: Relanding #2: Fixing crash that can occur if signal is modified while firing. (Closed)
Patch Set: Fixing issue with disconnect_all, adding test, simplifying code a bit Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/base/sigslot.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/base/sigslot_unittest.cc
diff --git a/webrtc/base/sigslot_unittest.cc b/webrtc/base/sigslot_unittest.cc
index e860fe33736da248646b40e475d92ccdf9b7d351..6d21d84fab4c1fe91011e2afcbdcbb0f5623615c 100644
--- a/webrtc/base/sigslot_unittest.cc
+++ b/webrtc/base/sigslot_unittest.cc
@@ -272,3 +272,86 @@ TEST(SigslotTest, CopyConnectedSlot) {
signal();
EXPECT_EQ(1, copied_receiver.signal_count());
}
+
+// Just used for the test below.
+class Disconnector : public sigslot::has_slots<> {
+ public:
+ Disconnector(SigslotReceiver<>* receiver1, SigslotReceiver<>* receiver2)
+ : receiver1_(receiver1), receiver2_(receiver2) {}
+
+ void Connect(sigslot::signal<>* signal) {
+ signal_ = signal;
+ signal->connect(this, &Disconnector::Disconnect);
+ }
+
+ private:
+ void Disconnect() {
+ receiver1_->Disconnect();
+ receiver2_->Disconnect();
+ signal_->disconnect(this);
+ }
+
+ sigslot::signal<>* signal_;
+ SigslotReceiver<>* receiver1_;
+ SigslotReceiver<>* receiver2_;
+};
+
+// Test that things work as expected if a signal is disconnected from a slot
+// while it's firing.
+TEST(SigslotTest, DisconnectFromSignalWhileFiring) {
+ sigslot::signal<> signal;
+ SigslotReceiver<> receiver1;
+ SigslotReceiver<> receiver2;
+ SigslotReceiver<> receiver3;
+ Disconnector disconnector(&receiver1, &receiver2);
+
+ // From this ordering, receiver1 should receive the signal, then the
+ // disconnector will be invoked, causing receiver2 to be disconnected before
+ // it receives the signal. And receiver3 should also receive the signal,
+ // since it was never disconnected.
+ receiver1.Connect(&signal);
+ disconnector.Connect(&signal);
+ receiver2.Connect(&signal);
+ receiver3.Connect(&signal);
+ signal();
+
+ EXPECT_EQ(1, receiver1.signal_count());
+ EXPECT_EQ(0, receiver2.signal_count());
+ EXPECT_EQ(1, receiver3.signal_count());
+}
+
+// Uses disconnect_all instead of disconnect.
+class Disconnector2 : public sigslot::has_slots<> {
+ public:
+ void Connect(sigslot::signal<>* signal) {
+ signal_ = signal;
+ signal->connect(this, &Disconnector2::Disconnect);
+ }
+
+ private:
+ void Disconnect() {
+ signal_->disconnect_all();
+ }
+
+ sigslot::signal<>* signal_;
+};
+
+// Test that things work as expected if a signal is disconnected from a slot
+// while it's firing using disconnect_all.
+TEST(SigslotTest, CallDisconnectAllWhileSignalFiring) {
+ sigslot::signal<> signal;
+ SigslotReceiver<> receiver1;
+ SigslotReceiver<> receiver2;
+ Disconnector2 disconnector;
+
+ // From this ordering, receiver1 should receive the signal, then the
+ // disconnector will be invoked, causing receiver2 to be disconnected before
+ // it receives the signal.
+ receiver1.Connect(&signal);
+ disconnector.Connect(&signal);
+ receiver2.Connect(&signal);
+ signal();
+
+ EXPECT_EQ(1, receiver1.signal_count());
+ EXPECT_EQ(0, receiver2.signal_count());
+}
« no previous file with comments | « webrtc/base/sigslot.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698