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()); |
+} |