thread_unittest.cc revision e93cbd13d51c59763476528bb2232903504f7457
1f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org/* 2f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * 4f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * Use of this source code is governed by a BSD-style license 5f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * that can be found in the LICENSE file in the root of the source 6f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * tree. An additional intellectual property rights grant can be found 7f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * in the file PATENTS. All contributing project authors may 8f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org */ 10f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 11f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/asyncinvoker.h" 12f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/asyncudpsocket.h" 13f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/event.h" 14f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/gunit.h" 15f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/physicalsocketserver.h" 16f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/socketaddress.h" 17f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include "webrtc/base/thread.h" 18fded02c164ea4cc3d28d7f30ac9ce9d94d76ef7ahenrike@webrtc.org#include "webrtc/test/testsupport/gtest_disable.h" 19f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 20f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#if defined(WEBRTC_WIN) 21f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#include <comdef.h> // NOLINT 22f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif 23f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 24f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgusing namespace rtc; 25f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 26f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Generates a sequence of numbers (collaboratively). 27f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgclass TestGenerator { 28f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org public: 29f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org TestGenerator() : last(0), count(0) {} 30f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 31f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int Next(int prev) { 32f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int result = prev + last; 33f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org last = result; 34f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org count += 1; 35f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return result; 36f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 37f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 38f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int last; 39f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int count; 40f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}; 41f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 42f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstruct TestMessage : public MessageData { 43f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org explicit TestMessage(int v) : value(v) {} 44f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org virtual ~TestMessage() {} 45f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 46f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int value; 47f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}; 48f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 49f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Receives on a socket and sends by posting messages. 50f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgclass SocketClient : public TestGenerator, public sigslot::has_slots<> { 51f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org public: 52f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SocketClient(AsyncSocket* socket, const SocketAddress& addr, 53f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Thread* post_thread, MessageHandler* phandler) 54f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org : socket_(AsyncUDPSocket::Create(socket, addr)), 55f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org post_thread_(post_thread), 56f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org post_handler_(phandler) { 57f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org socket_->SignalReadPacket.connect(this, &SocketClient::OnPacket); 58f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 59f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 60f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ~SocketClient() { 61f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete socket_; 62f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 63f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 64f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SocketAddress address() const { return socket_->GetLocalAddress(); } 65f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 66f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org void OnPacket(AsyncPacketSocket* socket, const char* buf, size_t size, 67f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const SocketAddress& remote_addr, 68f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const PacketTime& packet_time) { 69f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_EQ(size, sizeof(uint32)); 70f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org uint32 prev = reinterpret_cast<const uint32*>(buf)[0]; 71f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org uint32 result = Next(prev); 72f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 73f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org post_thread_->PostDelayed(200, post_handler_, 0, new TestMessage(result)); 74f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 75f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 76f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org private: 77f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org AsyncUDPSocket* socket_; 78f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Thread* post_thread_; 79f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org MessageHandler* post_handler_; 80f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}; 81f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 82f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Receives messages and sends on a socket. 83f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgclass MessageClient : public MessageHandler, public TestGenerator { 84f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org public: 85f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org MessageClient(Thread* pth, Socket* socket) 86f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org : socket_(socket) { 87f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 88f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 89f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org virtual ~MessageClient() { 90f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete socket_; 91f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 92f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 93f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org virtual void OnMessage(Message *pmsg) { 94f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org TestMessage* msg = static_cast<TestMessage*>(pmsg->pdata); 95f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int result = Next(msg->value); 96f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_GE(socket_->Send(&result, sizeof(result)), 0); 97f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete msg; 98f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 99f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 100f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org private: 101f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Socket* socket_; 102f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}; 103f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 104f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgclass CustomThread : public rtc::Thread { 105f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org public: 106f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org CustomThread() {} 107f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org virtual ~CustomThread() { Stop(); } 108f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bool Start() { return false; } 109ba737cba1aa6607911b1ca10460423b4c3e51fb9jiayl@webrtc.org 110ba737cba1aa6607911b1ca10460423b4c3e51fb9jiayl@webrtc.org bool WrapCurrent() { 111ba737cba1aa6607911b1ca10460423b4c3e51fb9jiayl@webrtc.org return Thread::WrapCurrent(); 112ba737cba1aa6607911b1ca10460423b4c3e51fb9jiayl@webrtc.org } 113ba737cba1aa6607911b1ca10460423b4c3e51fb9jiayl@webrtc.org void UnwrapCurrent() { 114ba737cba1aa6607911b1ca10460423b4c3e51fb9jiayl@webrtc.org Thread::UnwrapCurrent(); 115ba737cba1aa6607911b1ca10460423b4c3e51fb9jiayl@webrtc.org } 116f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}; 117f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 118f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 119f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// A thread that does nothing when it runs and signals an event 120f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// when it is destroyed. 121f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgclass SignalWhenDestroyedThread : public Thread { 122f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org public: 123f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SignalWhenDestroyedThread(Event* event) 124f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org : event_(event) { 125f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 126f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 127f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org virtual ~SignalWhenDestroyedThread() { 128f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Stop(); 129f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org event_->Set(); 130f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 131f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 132f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org virtual void Run() { 133f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Do nothing. 134f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 135f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 136f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org private: 137f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Event* event_; 138f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}; 139f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 140f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Function objects to test Thread::Invoke. 141f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstruct FunctorA { 142f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int operator()() { return 42; } 143f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}; 144f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgclass FunctorB { 145f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org public: 146f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org explicit FunctorB(bool* flag) : flag_(flag) {} 147f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org void operator()() { if (flag_) *flag_ = true; } 148f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org private: 149f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bool* flag_; 150f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}; 151f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgstruct FunctorC { 152f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int operator()() { 153f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Thread::Current()->ProcessMessages(50); 154f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org return 24; 155f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 156f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}; 157f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 158f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// See: https://code.google.com/p/webrtc/issues/detail?id=2409 159f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgTEST(ThreadTest, DISABLED_Main) { 160f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org const SocketAddress addr("127.0.0.1", 0); 161f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 162f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Create the messaging client on its own thread. 163f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Thread th1; 164f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Socket* socket = th1.socketserver()->CreateAsyncSocket(addr.family(), 165f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SOCK_DGRAM); 166f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org MessageClient msg_client(&th1, socket); 167f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 168f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Create the socket client on its own thread. 169f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Thread th2; 170f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org AsyncSocket* asocket = 171f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org th2.socketserver()->CreateAsyncSocket(addr.family(), SOCK_DGRAM); 172f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SocketClient sock_client(asocket, addr, &th1, &msg_client); 173f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 174f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org socket->Connect(sock_client.address()); 175f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 176f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org th1.Start(); 177f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org th2.Start(); 178f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 179f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Get the messages started. 180f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org th1.PostDelayed(100, &msg_client, 0, new TestMessage(1)); 181f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 182f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Give the clients a little while to run. 183f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Messages will be processed at 100, 300, 500, 700, 900. 184f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Thread* th_main = Thread::Current(); 185f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org th_main->ProcessMessages(1000); 186f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 187f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Stop the sending client. Give the receiver a bit longer to run, in case 188f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // it is running on a machine that is under load (e.g. the build machine). 189f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org th1.Stop(); 190f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org th_main->ProcessMessages(200); 191f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org th2.Stop(); 192f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 193f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Make sure the results were correct 194f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_EQ(5, msg_client.count); 195f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_EQ(34, msg_client.last); 196f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_EQ(5, sock_client.count); 197f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_EQ(55, sock_client.last); 198f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 199f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 200f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Test that setting thread names doesn't cause a malfunction. 201f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// There's no easy way to verify the name was set properly at this time. 202c732a3e5113bd64c85eeefa7a2ed3a5076e3db87henrike@webrtc.orgTEST(ThreadTest, Names) { 203f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Default name 204f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Thread *thread; 205f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org thread = new Thread(); 206f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_TRUE(thread->Start()); 207f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org thread->Stop(); 208f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete thread; 209f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org thread = new Thread(); 210f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Name with no object parameter 211f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_TRUE(thread->SetName("No object", NULL)); 212f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_TRUE(thread->Start()); 213f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org thread->Stop(); 214f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete thread; 215f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Really long name 216f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org thread = new Thread(); 217f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_TRUE(thread->SetName("Abcdefghijklmnopqrstuvwxyz1234567890", this)); 218f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_TRUE(thread->Start()); 219f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org thread->Stop(); 220f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete thread; 221f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 222f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 223f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// Test that setting thread priorities doesn't cause a malfunction. 224f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org// There's no easy way to verify the priority was set properly at this time. 225c732a3e5113bd64c85eeefa7a2ed3a5076e3db87henrike@webrtc.orgTEST(ThreadTest, Priorities) { 226f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Thread *thread; 227f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org thread = new Thread(); 228f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_TRUE(thread->SetPriority(PRIORITY_HIGH)); 229f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_TRUE(thread->Start()); 230f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org thread->Stop(); 231f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete thread; 232f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org thread = new Thread(); 233f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_TRUE(thread->SetPriority(PRIORITY_ABOVE_NORMAL)); 234f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_TRUE(thread->Start()); 235f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org thread->Stop(); 236f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete thread; 237f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 238f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org thread = new Thread(); 239f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_TRUE(thread->Start()); 240f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#if defined(WEBRTC_WIN) 241f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_TRUE(thread->SetPriority(PRIORITY_ABOVE_NORMAL)); 242f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#else 243f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_FALSE(thread->SetPriority(PRIORITY_ABOVE_NORMAL)); 244f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif 245f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org thread->Stop(); 246f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete thread; 247f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 248f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 249f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 250e30dab77dfaf4a156b50c899246c3734152d11b2henrike@webrtc.orgTEST(ThreadTest, Wrap) { 251e30dab77dfaf4a156b50c899246c3734152d11b2henrike@webrtc.org Thread* current_thread = Thread::Current(); 252e30dab77dfaf4a156b50c899246c3734152d11b2henrike@webrtc.org current_thread->UnwrapCurrent(); 253f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org CustomThread* cthread = new CustomThread(); 254f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_TRUE(cthread->WrapCurrent()); 255e5063b173303e9ee6c2246d2aa42a1480902b867fischman@webrtc.org EXPECT_TRUE(cthread->RunningForTest()); 256f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_FALSE(cthread->IsOwned()); 257f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org cthread->UnwrapCurrent(); 258e5063b173303e9ee6c2246d2aa42a1480902b867fischman@webrtc.org EXPECT_FALSE(cthread->RunningForTest()); 259f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete cthread; 260e30dab77dfaf4a156b50c899246c3734152d11b2henrike@webrtc.org current_thread->WrapCurrent(); 261f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 262f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 263c732a3e5113bd64c85eeefa7a2ed3a5076e3db87henrike@webrtc.orgTEST(ThreadTest, Invoke) { 264f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Create and start the thread. 265f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Thread thread; 266f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org thread.Start(); 267f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Try calling functors. 268f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_EQ(42, thread.Invoke<int>(FunctorA())); 269f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bool called = false; 270f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org FunctorB f2(&called); 271f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org thread.Invoke<void>(f2); 272f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_TRUE(called); 273f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Try calling bare functions. 274f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org struct LocalFuncs { 275f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org static int Func1() { return 999; } 276f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org static void Func2() {} 277f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org }; 278f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_EQ(999, thread.Invoke<int>(&LocalFuncs::Func1)); 279f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org thread.Invoke<void>(&LocalFuncs::Func2); 280f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 281f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 2823987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org// Verifies that two threads calling Invoke on each other at the same time does 2833987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org// not deadlock. 2843987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.orgTEST(ThreadTest, TwoThreadsInvokeNoDeadlock) { 2853987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org AutoThread thread; 2863987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org Thread* current_thread = Thread::Current(); 2873987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org ASSERT_TRUE(current_thread != NULL); 2883987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org 2893987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org Thread other_thread; 2903987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org other_thread.Start(); 2913987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org 2923987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org struct LocalFuncs { 2933987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org static void Set(bool* out) { *out = true; } 2943987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org static void InvokeSet(Thread* thread, bool* out) { 2953987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org thread->Invoke<void>(Bind(&Set, out)); 2963987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org } 2973987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org }; 2983987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org 2993987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org bool called = false; 3003987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org other_thread.Invoke<void>( 3013987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org Bind(&LocalFuncs::InvokeSet, current_thread, &called)); 3023987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org 3033987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org EXPECT_TRUE(called); 3043987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org} 3053987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org 3063987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org// Verifies that if thread A invokes a call on thread B and thread C is trying 3073987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org// to invoke A at the same time, thread A does not handle C's invoke while 3083987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org// invoking B. 3093987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.orgTEST(ThreadTest, ThreeThreadsInvoke) { 3103987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org AutoThread thread; 3113987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org Thread* thread_a = Thread::Current(); 3123987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org Thread thread_b, thread_c; 3133987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org thread_b.Start(); 3143987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org thread_c.Start(); 3153987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org 316e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org class LockedBool { 317e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org public: 318e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org explicit LockedBool(bool value) : value_(value) {} 319e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org 320e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org void Set(bool value) { 321e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org CritScope lock(&crit_); 322e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org value_ = value; 323e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org } 324e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org 325e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org bool Get() { 326e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org CritScope lock(&crit_); 327e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org return value_; 328e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org } 329e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org 330e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org private: 331e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org CriticalSection crit_; 332e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org bool value_ GUARDED_BY(crit_); 333e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org }; 334e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org 3353987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org struct LocalFuncs { 336e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org static void Set(LockedBool* out) { out->Set(true); } 337e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org static void InvokeSet(Thread* thread, LockedBool* out) { 3383987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org thread->Invoke<void>(Bind(&Set, out)); 3393987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org } 3403987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org 3413987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org // Set |out| true and call InvokeSet on |thread|. 342e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org static void SetAndInvokeSet(LockedBool* out, 343e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org Thread* thread, 344e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org LockedBool* out_inner) { 345e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org out->Set(true); 3463987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org InvokeSet(thread, out_inner); 3473987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org } 3483987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org 3493987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org // Asynchronously invoke SetAndInvokeSet on |thread1| and wait until 3503987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org // |thread1| starts the call. 3513987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org static void AsyncInvokeSetAndWait( 352e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org Thread* thread1, Thread* thread2, LockedBool* out) { 353e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org CriticalSection crit; 354e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org LockedBool async_invoked(false); 3553987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org 3563987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org AsyncInvoker invoker; 3573987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org invoker.AsyncInvoke<void>( 3583987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org thread1, Bind(&SetAndInvokeSet, &async_invoked, thread2, out)); 3593987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org 360e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org EXPECT_TRUE_WAIT(async_invoked.Get(), 2000); 3613987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org } 3623987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org }; 3633987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org 364e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org LockedBool thread_a_called(false); 3653987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org 3663987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org // Start the sequence A --(invoke)--> B --(async invoke)--> C --(invoke)--> A. 3673987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org // Thread B returns when C receives the call and C should be blocked until A 3683987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org // starts to process messages. 3693987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org thread_b.Invoke<void>(Bind(&LocalFuncs::AsyncInvokeSetAndWait, 3703987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org &thread_c, thread_a, &thread_a_called)); 371e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org EXPECT_FALSE(thread_a_called.Get()); 3723987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org 373e93cbd13d51c59763476528bb2232903504f7457pbos@webrtc.org EXPECT_TRUE_WAIT(thread_a_called.Get(), 2000); 3743987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org} 3753987b6de506a7e72a5bdfdf8c8ad9964705c5a28jiayl@webrtc.org 376f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgclass AsyncInvokeTest : public testing::Test { 377f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org public: 378f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org void IntCallback(int value) { 379f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_EQ(expected_thread_, Thread::Current()); 380f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int_value_ = value; 381f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 382f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org void AsyncInvokeIntCallback(AsyncInvoker* invoker, Thread* thread) { 383f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org expected_thread_ = thread; 384f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org invoker->AsyncInvoke(thread, FunctorC(), 385f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org &AsyncInvokeTest::IntCallback, 386f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org static_cast<AsyncInvokeTest*>(this)); 387f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org invoke_started_.Set(); 388f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 389f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org void SetExpectedThreadForIntCallback(Thread* thread) { 390f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org expected_thread_ = thread; 391f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 392f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 393f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org protected: 394f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org enum { kWaitTimeout = 1000 }; 395f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org AsyncInvokeTest() 396f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org : int_value_(0), 397f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org invoke_started_(true, false), 398f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org expected_thread_(NULL) {} 399f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 400f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org int int_value_; 401f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Event invoke_started_; 402f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Thread* expected_thread_; 403f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}; 404f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 405e30dab77dfaf4a156b50c899246c3734152d11b2henrike@webrtc.orgTEST_F(AsyncInvokeTest, FireAndForget) { 406f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org AsyncInvoker invoker; 407f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Create and start the thread. 408f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Thread thread; 409f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org thread.Start(); 410f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Try calling functor. 411f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bool called = false; 412f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org invoker.AsyncInvoke<void>(&thread, FunctorB(&called)); 413f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_TRUE_WAIT(called, kWaitTimeout); 414f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 415f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 416c732a3e5113bd64c85eeefa7a2ed3a5076e3db87henrike@webrtc.orgTEST_F(AsyncInvokeTest, WithCallback) { 417f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org AsyncInvoker invoker; 418f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Create and start the thread. 419f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Thread thread; 420f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org thread.Start(); 421f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Try calling functor. 422f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org SetExpectedThreadForIntCallback(Thread::Current()); 423f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org invoker.AsyncInvoke(&thread, FunctorA(), 424f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org &AsyncInvokeTest::IntCallback, 425f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org static_cast<AsyncInvokeTest*>(this)); 426f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_EQ_WAIT(42, int_value_, kWaitTimeout); 427f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 428f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 429c732a3e5113bd64c85eeefa7a2ed3a5076e3db87henrike@webrtc.orgTEST_F(AsyncInvokeTest, CancelInvoker) { 430f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Create and start the thread. 431f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Thread thread; 432f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org thread.Start(); 433f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Try destroying invoker during call. 434f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org { 435f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org AsyncInvoker invoker; 436f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org invoker.AsyncInvoke(&thread, FunctorC(), 437f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org &AsyncInvokeTest::IntCallback, 438f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org static_cast<AsyncInvokeTest*>(this)); 439f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 440f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // With invoker gone, callback should be cancelled. 441f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Thread::Current()->ProcessMessages(kWaitTimeout); 442f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_EQ(0, int_value_); 443f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 444f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 445c732a3e5113bd64c85eeefa7a2ed3a5076e3db87henrike@webrtc.orgTEST_F(AsyncInvokeTest, CancelCallingThread) { 446f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org AsyncInvoker invoker; 447f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org { // Create and start the thread. 448f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Thread thread; 449f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org thread.Start(); 450f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Try calling functor. 451f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org thread.Invoke<void>(Bind(&AsyncInvokeTest::AsyncInvokeIntCallback, 452f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org static_cast<AsyncInvokeTest*>(this), 453f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org &invoker, Thread::Current())); 454f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Wait for the call to begin. 455f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ASSERT_TRUE(invoke_started_.Wait(kWaitTimeout)); 456f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 457f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Calling thread is gone. Return message shouldn't happen. 458f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Thread::Current()->ProcessMessages(kWaitTimeout); 459f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_EQ(0, int_value_); 460f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 461f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 462c732a3e5113bd64c85eeefa7a2ed3a5076e3db87henrike@webrtc.orgTEST_F(AsyncInvokeTest, KillInvokerBeforeExecute) { 463f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Thread thread; 464f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org thread.Start(); 465f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org { 466f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org AsyncInvoker invoker; 467f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Try calling functor. 468f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org thread.Invoke<void>(Bind(&AsyncInvokeTest::AsyncInvokeIntCallback, 469f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org static_cast<AsyncInvokeTest*>(this), 470f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org &invoker, Thread::Current())); 471f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Wait for the call to begin. 472f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ASSERT_TRUE(invoke_started_.Wait(kWaitTimeout)); 473f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 474f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Invoker is destroyed. Function should not execute. 475f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Thread::Current()->ProcessMessages(kWaitTimeout); 476f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_EQ(0, int_value_); 477f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 478f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 479c732a3e5113bd64c85eeefa7a2ed3a5076e3db87henrike@webrtc.orgTEST_F(AsyncInvokeTest, Flush) { 480f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org AsyncInvoker invoker; 481f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bool flag1 = false; 482f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bool flag2 = false; 483f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Queue two async calls to the current thread. 484f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org invoker.AsyncInvoke<void>(Thread::Current(), 485f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org FunctorB(&flag1)); 486f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org invoker.AsyncInvoke<void>(Thread::Current(), 487f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org FunctorB(&flag2)); 488f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Because we haven't pumped messages, these should not have run yet. 489f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_FALSE(flag1); 490f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_FALSE(flag2); 491f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Force them to run now. 492f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org invoker.Flush(Thread::Current()); 493f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_TRUE(flag1); 494f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_TRUE(flag2); 495f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 496f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 497c732a3e5113bd64c85eeefa7a2ed3a5076e3db87henrike@webrtc.orgTEST_F(AsyncInvokeTest, FlushWithIds) { 498f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org AsyncInvoker invoker; 499f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bool flag1 = false; 500f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bool flag2 = false; 501f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Queue two async calls to the current thread, one with a message id. 502f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org invoker.AsyncInvoke<void>(Thread::Current(), 503f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org FunctorB(&flag1), 504f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 5); 505f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org invoker.AsyncInvoke<void>(Thread::Current(), 506f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org FunctorB(&flag2)); 507f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Because we haven't pumped messages, these should not have run yet. 508f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_FALSE(flag1); 509f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_FALSE(flag2); 510f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Execute pending calls with id == 5. 511f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org invoker.Flush(Thread::Current(), 5); 512f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_TRUE(flag1); 513f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_FALSE(flag2); 514f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org flag1 = false; 515f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // Execute all pending calls. The id == 5 call should not execute again. 516f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org invoker.Flush(Thread::Current()); 517f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_FALSE(flag1); 518f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_TRUE(flag2); 519f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 520f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 521f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 522f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#if defined(WEBRTC_WIN) 523f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgclass ComThreadTest : public testing::Test, public MessageHandler { 524f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org public: 525f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org ComThreadTest() : done_(false) {} 526f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org protected: 527f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org virtual void OnMessage(Message* message) { 528f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); 529f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org // S_FALSE means the thread was already inited for a multithread apartment. 530f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_EQ(S_FALSE, hr); 531f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org if (SUCCEEDED(hr)) { 532f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org CoUninitialize(); 533f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 534f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org done_ = true; 535f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org } 536f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org bool done_; 537f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org}; 538f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org 539f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.orgTEST_F(ComThreadTest, ComInited) { 540f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org Thread* thread = new ComThread(); 541f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_TRUE(thread->Start()); 542f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org thread->Post(this, 0); 543f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org EXPECT_TRUE_WAIT(done_, 1000); 544f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org delete thread; 545f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org} 546f048872e915a3ee229044ec4bc541f6cbf9e4de1henrike@webrtc.org#endif 547