15976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/*
25976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * libjingle
35976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Copyright 2012, Google Inc.
45976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *
55976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Redistribution and use in source and binary forms, with or without
65976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * modification, are permitted provided that the following conditions are met:
75976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *
85976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *  1. Redistributions of source code must retain the above copyright notice,
95976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *     this list of conditions and the following disclaimer.
105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *  2. Redistributions in binary form must reproduce the above copyright notice,
115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *     this list of conditions and the following disclaimer in the documentation
125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *     and/or other materials provided with the distribution.
135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *  3. The name of the author may not be used to endorse or promote products
145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *     derived from this software without specific prior written permission.
155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *
165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org */
275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/sigslot.h"
295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/gunit.h"
315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// This function, when passed a has_slots or signalx, will break the build if
335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// its threading requirement is not single threaded
345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic bool TemplateIsST(const sigslot::single_threaded* p) {
355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return true;
365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// This function, when passed a has_slots or signalx, will break the build if
385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// its threading requirement is not multi threaded
395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic bool TemplateIsMT(const sigslot::multi_threaded_local* p) {
405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return true;
415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass SigslotDefault : public testing::Test, public sigslot::has_slots<> {
445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org protected:
455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  sigslot::signal0<> signal_;
465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org};
475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgtemplate<class slot_policy = sigslot::single_threaded,
495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org         class signal_policy = sigslot::single_threaded>
505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass SigslotReceiver : public sigslot::has_slots<slot_policy> {
515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public:
525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SigslotReceiver() : signal_(NULL), signal_count_(0) {
535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  ~SigslotReceiver() {
555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void Connect(sigslot::signal0<signal_policy>* signal) {
585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (!signal) return;
595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    Disconnect();
605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    signal_ = signal;
615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    signal->connect(this,
625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                    &SigslotReceiver<slot_policy, signal_policy>::OnSignal);
635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void Disconnect() {
655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (!signal_) return;
665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    signal_->disconnect(this);
675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    signal_ = NULL;
685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void OnSignal() {
705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ++signal_count_;
715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  int signal_count() { return signal_count_; }
735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org private:
755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  sigslot::signal0<signal_policy>* signal_;
765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  int signal_count_;
775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org};
785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgtemplate<class slot_policy = sigslot::single_threaded,
805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org         class mt_signal_policy = sigslot::multi_threaded_local>
815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass SigslotSlotTest : public testing::Test {
825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org protected:
835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SigslotSlotTest() {
845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    mt_signal_policy mt_policy;
855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    TemplateIsMT(&mt_policy);
865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual void SetUp() {
895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    Connect();
905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual void TearDown() {
925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    Disconnect();
935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void Disconnect() {
965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    st_receiver_.Disconnect();
975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    mt_receiver_.Disconnect();
985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void Connect() {
1015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    st_receiver_.Connect(&SignalSTLoopback);
1025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    mt_receiver_.Connect(&SignalMTLoopback);
1035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  int st_loop_back_count() { return st_receiver_.signal_count(); }
1065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  int mt_loop_back_count() { return mt_receiver_.signal_count(); }
1075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  sigslot::signal0<> SignalSTLoopback;
1095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SigslotReceiver<slot_policy, sigslot::single_threaded> st_receiver_;
1105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  sigslot::signal0<mt_signal_policy> SignalMTLoopback;
1115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SigslotReceiver<slot_policy, mt_signal_policy> mt_receiver_;
1125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org};
1135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgtypedef SigslotSlotTest<> SigslotSTSlotTest;
1155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgtypedef SigslotSlotTest<sigslot::multi_threaded_local,
1165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                        sigslot::multi_threaded_local> SigslotMTSlotTest;
1175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass multi_threaded_local_fake : public sigslot::multi_threaded_local {
1195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public:
1205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  multi_threaded_local_fake() : lock_count_(0), unlock_count_(0) {
1215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual void lock() {
1245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ++lock_count_;
1255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual void unlock() {
1275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ++unlock_count_;
1285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  int lock_count() { return lock_count_; }
1315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool InCriticalSection() { return lock_count_ != unlock_count_; }
1335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org protected:
1355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  int lock_count_;
1365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  int unlock_count_;
1375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org};
1385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgtypedef SigslotSlotTest<multi_threaded_local_fake,
1405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                        multi_threaded_local_fake> SigslotMTLockBase;
1415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass SigslotMTLockTest : public SigslotMTLockBase {
1435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org protected:
1445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SigslotMTLockTest() {}
1455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual void SetUp() {
1475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(0, SlotLockCount());
1485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    SigslotMTLockBase::SetUp();
1495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Connects to two signals (ST and MT). However,
1505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // SlotLockCount() only gets the count for the
1515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // MT signal (there are two separate SigslotReceiver which
1525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // keep track of their own count).
1535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(1, SlotLockCount());
1545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual void TearDown() {
1565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const int previous_lock_count = SlotLockCount();
1575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    SigslotMTLockBase::TearDown();
1585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Disconnects from two signals. Note analogous to SetUp().
1595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(previous_lock_count + 1, SlotLockCount());
1605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  int SlotLockCount() { return mt_receiver_.lock_count(); }
1635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void Signal() { SignalMTLoopback(); }
1645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  int SignalLockCount() { return SignalMTLoopback.lock_count(); }
1655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  int signal_count() { return mt_loop_back_count(); }
1665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool InCriticalSection() { return SignalMTLoopback.InCriticalSection(); }
1675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org};
1685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// This test will always succeed. However, if the default template instantiation
1705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// changes from single threaded to multi threaded it will break the build here.
1715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SigslotDefault, DefaultIsST) {
1725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_TRUE(TemplateIsST(this));
1735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_TRUE(TemplateIsST(&signal_));
1745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// ST slot, ST signal
1775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SigslotSTSlotTest, STLoopbackTest) {
1785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SignalSTLoopback();
1795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_EQ(1, st_loop_back_count());
1805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_EQ(0, mt_loop_back_count());
1815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// ST slot, MT signal
1845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SigslotSTSlotTest, MTLoopbackTest) {
1855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SignalMTLoopback();
1865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_EQ(1, mt_loop_back_count());
1875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_EQ(0, st_loop_back_count());
1885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// ST slot, both ST and MT (separate) signal
1915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SigslotSTSlotTest, AllLoopbackTest) {
1925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SignalSTLoopback();
1935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SignalMTLoopback();
1945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_EQ(1, mt_loop_back_count());
1955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_EQ(1, st_loop_back_count());
1965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SigslotSTSlotTest, Reconnect) {
1995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SignalSTLoopback();
2005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SignalMTLoopback();
2015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_EQ(1, mt_loop_back_count());
2025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_EQ(1, st_loop_back_count());
2035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  Disconnect();
2045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SignalSTLoopback();
2055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SignalMTLoopback();
2065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_EQ(1, mt_loop_back_count());
2075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_EQ(1, st_loop_back_count());
2085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  Connect();
2095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SignalSTLoopback();
2105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SignalMTLoopback();
2115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_EQ(2, mt_loop_back_count());
2125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_EQ(2, st_loop_back_count());
2135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// MT slot, ST signal
2165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SigslotMTSlotTest, STLoopbackTest) {
2175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SignalSTLoopback();
2185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_EQ(1, st_loop_back_count());
2195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_EQ(0, mt_loop_back_count());
2205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// MT slot, MT signal
2235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SigslotMTSlotTest, MTLoopbackTest) {
2245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SignalMTLoopback();
2255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_EQ(1, mt_loop_back_count());
2265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_EQ(0, st_loop_back_count());
2275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// MT slot, both ST and MT (separate) signal
2305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SigslotMTSlotTest, AllLoopbackTest) {
2315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SignalMTLoopback();
2325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SignalSTLoopback();
2335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_EQ(1, st_loop_back_count());
2345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_EQ(1, mt_loop_back_count());
2355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Test that locks are acquired and released correctly.
2385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SigslotMTLockTest, LockSanity) {
2395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  const int lock_count = SignalLockCount();
2405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  Signal();
2415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_FALSE(InCriticalSection());
2425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_EQ(lock_count + 1, SignalLockCount());
2435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_EQ(1, signal_count());
2445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Destroy signal and slot in different orders.
2475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST(DestructionOrder, SignalFirst) {
2485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  sigslot::signal0<>* signal = new sigslot::signal0<>;
2495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SigslotReceiver<>* receiver = new SigslotReceiver<>();
2505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  receiver->Connect(signal);
2515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  (*signal)();
2525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_EQ(1, receiver->signal_count());
2535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  delete signal;
2545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  delete receiver;
2555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST(DestructionOrder, SlotFirst) {
2585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  sigslot::signal0<>* signal = new sigslot::signal0<>;
2595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SigslotReceiver<>* receiver = new SigslotReceiver<>();
2605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  receiver->Connect(signal);
2615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  (*signal)();
2625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  EXPECT_EQ(1, receiver->signal_count());
2635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  delete receiver;
2655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  (*signal)();
2665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  delete signal;
2675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
268