147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/* 247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * Copyright 2004 The WebRTC Project Authors. All rights reserved. 347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * 447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * Use of this source code is governed by a BSD-style license 547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * that can be found in the LICENSE file in the root of the source 647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * tree. An additional intellectual property rights grant can be found 747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * in the file PATENTS. All contributing project authors may 847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org * be found in the AUTHORS file in the root of the source tree. 947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */ 1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/asyncinvoker.h" 1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/asyncudpsocket.h" 1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/event.h" 1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/gunit.h" 1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/physicalsocketserver.h" 1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/socketaddress.h" 1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/thread.h" 18a127c9555d5bc8d9404562840ebfd5281c670600henrike@webrtc.org#include "webrtc/test/testsupport/gtest_disable.h" 1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN) 2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <comdef.h> // NOLINT 2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgusing namespace rtc; 2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Generates a sequence of numbers (collaboratively). 2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass TestGenerator { 2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public: 2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org TestGenerator() : last(0), count(0) {} 3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int Next(int prev) { 3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int result = prev + last; 3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org last = result; 3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org count += 1; 3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return result; 3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int last; 3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int count; 4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstruct TestMessage : public MessageData { 4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org explicit TestMessage(int v) : value(v) {} 4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual ~TestMessage() {} 4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int value; 4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Receives on a socket and sends by posting messages. 5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass SocketClient : public TestGenerator, public sigslot::has_slots<> { 5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public: 5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SocketClient(AsyncSocket* socket, const SocketAddress& addr, 5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Thread* post_thread, MessageHandler* phandler) 5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org : socket_(AsyncUDPSocket::Create(socket, addr)), 5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org post_thread_(post_thread), 5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org post_handler_(phandler) { 5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org socket_->SignalReadPacket.connect(this, &SocketClient::OnPacket); 5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ~SocketClient() { 6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org delete socket_; 6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SocketAddress address() const { return socket_->GetLocalAddress(); } 6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org void OnPacket(AsyncPacketSocket* socket, const char* buf, size_t size, 6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const SocketAddress& remote_addr, 6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const PacketTime& packet_time) { 6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_EQ(size, sizeof(uint32)); 7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org uint32 prev = reinterpret_cast<const uint32*>(buf)[0]; 7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org uint32 result = Next(prev); 7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org post_thread_->PostDelayed(200, post_handler_, 0, new TestMessage(result)); 7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org private: 7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncUDPSocket* socket_; 7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Thread* post_thread_; 7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org MessageHandler* post_handler_; 8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Receives messages and sends on a socket. 8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass MessageClient : public MessageHandler, public TestGenerator { 8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public: 8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org MessageClient(Thread* pth, Socket* socket) 8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org : socket_(socket) { 8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual ~MessageClient() { 9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org delete socket_; 9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual void OnMessage(Message *pmsg) { 9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org TestMessage* msg = static_cast<TestMessage*>(pmsg->pdata); 9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int result = Next(msg->value); 9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_GE(socket_->Send(&result, sizeof(result)), 0); 9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org delete msg; 9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org private: 10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Socket* socket_; 10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass CustomThread : public rtc::Thread { 10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public: 10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org CustomThread() {} 10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual ~CustomThread() { Stop(); } 10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool Start() { return false; } 109692b0633dd5ffbd0235a73a6f4f7cf864e78b285jiayl@webrtc.org 110692b0633dd5ffbd0235a73a6f4f7cf864e78b285jiayl@webrtc.org bool WrapCurrent() { 111692b0633dd5ffbd0235a73a6f4f7cf864e78b285jiayl@webrtc.org return Thread::WrapCurrent(); 112692b0633dd5ffbd0235a73a6f4f7cf864e78b285jiayl@webrtc.org } 113692b0633dd5ffbd0235a73a6f4f7cf864e78b285jiayl@webrtc.org void UnwrapCurrent() { 114692b0633dd5ffbd0235a73a6f4f7cf864e78b285jiayl@webrtc.org Thread::UnwrapCurrent(); 115692b0633dd5ffbd0235a73a6f4f7cf864e78b285jiayl@webrtc.org } 11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// A thread that does nothing when it runs and signals an event 12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// when it is destroyed. 12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass SignalWhenDestroyedThread : public Thread { 12247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public: 12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SignalWhenDestroyedThread(Event* event) 12447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org : event_(event) { 12547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 12647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 12747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual ~SignalWhenDestroyedThread() { 12847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Stop(); 12947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org event_->Set(); 13047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 13147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 13247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual void Run() { 13347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Do nothing. 13447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 13547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 13647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org private: 13747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Event* event_; 13847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 13947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 14047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Function objects to test Thread::Invoke. 14147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstruct FunctorA { 14247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int operator()() { return 42; } 14347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 14447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass FunctorB { 14547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public: 14647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org explicit FunctorB(bool* flag) : flag_(flag) {} 14747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org void operator()() { if (flag_) *flag_ = true; } 14847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org private: 14947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool* flag_; 15047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 15147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstruct FunctorC { 15247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int operator()() { 15347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Thread::Current()->ProcessMessages(50); 15447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org return 24; 15547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 15647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 15747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 15847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// See: https://code.google.com/p/webrtc/issues/detail?id=2409 15947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgTEST(ThreadTest, DISABLED_Main) { 16047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org const SocketAddress addr("127.0.0.1", 0); 16147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 16247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Create the messaging client on its own thread. 16347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Thread th1; 16447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Socket* socket = th1.socketserver()->CreateAsyncSocket(addr.family(), 16547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SOCK_DGRAM); 16647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org MessageClient msg_client(&th1, socket); 16747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 16847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Create the socket client on its own thread. 16947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Thread th2; 17047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncSocket* asocket = 17147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org th2.socketserver()->CreateAsyncSocket(addr.family(), SOCK_DGRAM); 17247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SocketClient sock_client(asocket, addr, &th1, &msg_client); 17347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 17447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org socket->Connect(sock_client.address()); 17547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 17647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org th1.Start(); 17747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org th2.Start(); 17847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 17947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Get the messages started. 18047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org th1.PostDelayed(100, &msg_client, 0, new TestMessage(1)); 18147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 18247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Give the clients a little while to run. 18347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Messages will be processed at 100, 300, 500, 700, 900. 18447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Thread* th_main = Thread::Current(); 18547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org th_main->ProcessMessages(1000); 18647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 18747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Stop the sending client. Give the receiver a bit longer to run, in case 18847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // it is running on a machine that is under load (e.g. the build machine). 18947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org th1.Stop(); 19047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org th_main->ProcessMessages(200); 19147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org th2.Stop(); 19247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 19347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Make sure the results were correct 19447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_EQ(5, msg_client.count); 19547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_EQ(34, msg_client.last); 19647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_EQ(5, sock_client.count); 19747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_EQ(55, sock_client.last); 19847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 19947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 20047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Test that setting thread names doesn't cause a malfunction. 20147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// There's no easy way to verify the name was set properly at this time. 202a127c9555d5bc8d9404562840ebfd5281c670600henrike@webrtc.orgTEST(ThreadTest, DISABLED_ON_MAC(Names)) { 20347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Default name 20447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Thread *thread; 20547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org thread = new Thread(); 20647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_TRUE(thread->Start()); 20747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org thread->Stop(); 20847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org delete thread; 20947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org thread = new Thread(); 21047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Name with no object parameter 21147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_TRUE(thread->SetName("No object", NULL)); 21247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_TRUE(thread->Start()); 21347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org thread->Stop(); 21447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org delete thread; 21547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Really long name 21647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org thread = new Thread(); 21747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_TRUE(thread->SetName("Abcdefghijklmnopqrstuvwxyz1234567890", this)); 21847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_TRUE(thread->Start()); 21947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org thread->Stop(); 22047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org delete thread; 22147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 22247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 22347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Test that setting thread priorities doesn't cause a malfunction. 22447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// There's no easy way to verify the priority was set properly at this time. 225a127c9555d5bc8d9404562840ebfd5281c670600henrike@webrtc.orgTEST(ThreadTest, DISABLED_ON_MAC(Priorities)) { 22647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Thread *thread; 22747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org thread = new Thread(); 22847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_TRUE(thread->SetPriority(PRIORITY_HIGH)); 22947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_TRUE(thread->Start()); 23047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org thread->Stop(); 23147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org delete thread; 23247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org thread = new Thread(); 23347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_TRUE(thread->SetPriority(PRIORITY_ABOVE_NORMAL)); 23447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_TRUE(thread->Start()); 23547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org thread->Stop(); 23647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org delete thread; 23747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 23847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org thread = new Thread(); 23947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_TRUE(thread->Start()); 24047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN) 24147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_TRUE(thread->SetPriority(PRIORITY_ABOVE_NORMAL)); 24247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#else 24347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_FALSE(thread->SetPriority(PRIORITY_ABOVE_NORMAL)); 24447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 24547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org thread->Stop(); 24647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org delete thread; 24747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 24847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 24947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 250a127c9555d5bc8d9404562840ebfd5281c670600henrike@webrtc.orgTEST(ThreadTest, DISABLED_ON_MAC(Wrap)) { 25147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org CustomThread* cthread = new CustomThread(); 25247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_TRUE(cthread->WrapCurrent()); 2530631e37660e5e9b1566089c8306094ad6ee9516efischman@webrtc.org EXPECT_TRUE(cthread->RunningForTest()); 25447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_FALSE(cthread->IsOwned()); 25547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org cthread->UnwrapCurrent(); 2560631e37660e5e9b1566089c8306094ad6ee9516efischman@webrtc.org EXPECT_FALSE(cthread->RunningForTest()); 25747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org delete cthread; 25847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 25947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 260a127c9555d5bc8d9404562840ebfd5281c670600henrike@webrtc.orgTEST(ThreadTest, DISABLED_ON_MAC(Invoke)) { 26147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Create and start the thread. 26247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Thread thread; 26347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org thread.Start(); 26447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Try calling functors. 26547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_EQ(42, thread.Invoke<int>(FunctorA())); 26647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool called = false; 26747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org FunctorB f2(&called); 26847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org thread.Invoke<void>(f2); 26947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_TRUE(called); 27047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Try calling bare functions. 27147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org struct LocalFuncs { 27247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org static int Func1() { return 999; } 27347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org static void Func2() {} 27447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org }; 27547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_EQ(999, thread.Invoke<int>(&LocalFuncs::Func1)); 27647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org thread.Invoke<void>(&LocalFuncs::Func2); 27747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 27847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 2798fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org// Verifies that two threads calling Invoke on each other at the same time does 2808fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org// not deadlock. 2818fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.orgTEST(ThreadTest, TwoThreadsInvokeNoDeadlock) { 2828fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org AutoThread thread; 2838fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org Thread* current_thread = Thread::Current(); 2848fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org ASSERT_TRUE(current_thread != NULL); 2858fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org 2868fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org Thread other_thread; 2878fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org other_thread.Start(); 2888fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org 2898fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org struct LocalFuncs { 2908fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org static void Set(bool* out) { *out = true; } 2918fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org static void InvokeSet(Thread* thread, bool* out) { 2928fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org thread->Invoke<void>(Bind(&Set, out)); 2938fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org } 2948fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org }; 2958fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org 2968fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org bool called = false; 2978fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org other_thread.Invoke<void>( 2988fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org Bind(&LocalFuncs::InvokeSet, current_thread, &called)); 2998fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org 3008fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org EXPECT_TRUE(called); 3018fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org} 3028fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org 3038fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org// Verifies that if thread A invokes a call on thread B and thread C is trying 3048fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org// to invoke A at the same time, thread A does not handle C's invoke while 3058fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org// invoking B. 3068fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.orgTEST(ThreadTest, ThreeThreadsInvoke) { 3078fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org AutoThread thread; 3088fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org Thread* thread_a = Thread::Current(); 3098fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org Thread thread_b, thread_c; 3108fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org thread_b.Start(); 3118fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org thread_c.Start(); 3128fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org 3138fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org struct LocalFuncs { 3148fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org static void Set(bool* out) { *out = true; } 3158fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org static void InvokeSet(Thread* thread, bool* out) { 3168fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org thread->Invoke<void>(Bind(&Set, out)); 3178fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org } 3188fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org 3198fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org // Set |out| true and call InvokeSet on |thread|. 3208fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org static void SetAndInvokeSet(bool* out, Thread* thread, bool* out_inner) { 3218fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org *out = true; 3228fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org InvokeSet(thread, out_inner); 3238fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org } 3248fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org 3258fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org // Asynchronously invoke SetAndInvokeSet on |thread1| and wait until 3268fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org // |thread1| starts the call. 3278fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org static void AsyncInvokeSetAndWait( 3288fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org Thread* thread1, Thread* thread2, bool* out) { 3298fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org bool async_invoked = false; 3308fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org 3318fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org AsyncInvoker invoker; 3328fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org invoker.AsyncInvoke<void>( 3338fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org thread1, Bind(&SetAndInvokeSet, &async_invoked, thread2, out)); 3348fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org 3358fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org EXPECT_TRUE_WAIT(async_invoked, 2000); 3368fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org } 3378fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org }; 3388fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org 3398fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org bool thread_a_called = false; 3408fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org 3418fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org // Start the sequence A --(invoke)--> B --(async invoke)--> C --(invoke)--> A. 3428fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org // Thread B returns when C receives the call and C should be blocked until A 3438fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org // starts to process messages. 3448fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org thread_b.Invoke<void>(Bind(&LocalFuncs::AsyncInvokeSetAndWait, 3458fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org &thread_c, thread_a, &thread_a_called)); 3468fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org EXPECT_FALSE(thread_a_called); 3478fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org 3488fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org EXPECT_TRUE_WAIT(thread_a_called, 2000); 3498fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org} 3508fd0eda9a5709127accccba383b258faf3503d2bjiayl@webrtc.org 35147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass AsyncInvokeTest : public testing::Test { 35247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public: 35347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org void IntCallback(int value) { 35447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_EQ(expected_thread_, Thread::Current()); 35547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int_value_ = value; 35647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 35747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org void AsyncInvokeIntCallback(AsyncInvoker* invoker, Thread* thread) { 35847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org expected_thread_ = thread; 35947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org invoker->AsyncInvoke(thread, FunctorC(), 36047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org &AsyncInvokeTest::IntCallback, 36147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org static_cast<AsyncInvokeTest*>(this)); 36247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org invoke_started_.Set(); 36347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 36447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org void SetExpectedThreadForIntCallback(Thread* thread) { 36547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org expected_thread_ = thread; 36647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 36747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 36847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org protected: 36947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org enum { kWaitTimeout = 1000 }; 37047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncInvokeTest() 37147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org : int_value_(0), 37247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org invoke_started_(true, false), 37347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org expected_thread_(NULL) {} 37447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 37547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org int int_value_; 37647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Event invoke_started_; 37747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Thread* expected_thread_; 37847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 37947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 380f46745bdccbac4672fc6fb9b543c4681d0fa7c42kjellander@webrtc.orgTEST_F(AsyncInvokeTest, DISABLED_FireAndForget) { 38147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncInvoker invoker; 38247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Create and start the thread. 38347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Thread thread; 38447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org thread.Start(); 38547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Try calling functor. 38647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool called = false; 38747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org invoker.AsyncInvoke<void>(&thread, FunctorB(&called)); 38847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_TRUE_WAIT(called, kWaitTimeout); 38947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 39047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 391f46745bdccbac4672fc6fb9b543c4681d0fa7c42kjellander@webrtc.orgTEST_F(AsyncInvokeTest, DISABLED_WithCallback) { 39247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncInvoker invoker; 39347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Create and start the thread. 39447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Thread thread; 39547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org thread.Start(); 39647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Try calling functor. 39747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org SetExpectedThreadForIntCallback(Thread::Current()); 39847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org invoker.AsyncInvoke(&thread, FunctorA(), 39947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org &AsyncInvokeTest::IntCallback, 40047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org static_cast<AsyncInvokeTest*>(this)); 40147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_EQ_WAIT(42, int_value_, kWaitTimeout); 40247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 40347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 404f46745bdccbac4672fc6fb9b543c4681d0fa7c42kjellander@webrtc.orgTEST_F(AsyncInvokeTest, DISABLED_CancelInvoker) { 40547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Create and start the thread. 40647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Thread thread; 40747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org thread.Start(); 40847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Try destroying invoker during call. 40947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org { 41047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncInvoker invoker; 41147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org invoker.AsyncInvoke(&thread, FunctorC(), 41247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org &AsyncInvokeTest::IntCallback, 41347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org static_cast<AsyncInvokeTest*>(this)); 41447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 41547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // With invoker gone, callback should be cancelled. 41647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Thread::Current()->ProcessMessages(kWaitTimeout); 41747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_EQ(0, int_value_); 41847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 41947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 420f46745bdccbac4672fc6fb9b543c4681d0fa7c42kjellander@webrtc.orgTEST_F(AsyncInvokeTest, DISABLED_CancelCallingThread) { 42147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncInvoker invoker; 42247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org { // Create and start the thread. 42347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Thread thread; 42447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org thread.Start(); 42547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Try calling functor. 42647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org thread.Invoke<void>(Bind(&AsyncInvokeTest::AsyncInvokeIntCallback, 42747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org static_cast<AsyncInvokeTest*>(this), 42847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org &invoker, Thread::Current())); 42947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Wait for the call to begin. 43047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT_TRUE(invoke_started_.Wait(kWaitTimeout)); 43147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 43247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Calling thread is gone. Return message shouldn't happen. 43347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Thread::Current()->ProcessMessages(kWaitTimeout); 43447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_EQ(0, int_value_); 43547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 43647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 437f46745bdccbac4672fc6fb9b543c4681d0fa7c42kjellander@webrtc.orgTEST_F(AsyncInvokeTest, DISABLED_KillInvokerBeforeExecute) { 43847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Thread thread; 43947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org thread.Start(); 44047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org { 44147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncInvoker invoker; 44247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Try calling functor. 44347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org thread.Invoke<void>(Bind(&AsyncInvokeTest::AsyncInvokeIntCallback, 44447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org static_cast<AsyncInvokeTest*>(this), 44547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org &invoker, Thread::Current())); 44647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Wait for the call to begin. 44747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ASSERT_TRUE(invoke_started_.Wait(kWaitTimeout)); 44847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 44947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Invoker is destroyed. Function should not execute. 45047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Thread::Current()->ProcessMessages(kWaitTimeout); 45147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_EQ(0, int_value_); 45247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 45347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 454f46745bdccbac4672fc6fb9b543c4681d0fa7c42kjellander@webrtc.orgTEST_F(AsyncInvokeTest, DISABLED_Flush) { 45547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncInvoker invoker; 45647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool flag1 = false; 45747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool flag2 = false; 45847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Queue two async calls to the current thread. 45947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org invoker.AsyncInvoke<void>(Thread::Current(), 46047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org FunctorB(&flag1)); 46147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org invoker.AsyncInvoke<void>(Thread::Current(), 46247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org FunctorB(&flag2)); 46347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Because we haven't pumped messages, these should not have run yet. 46447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_FALSE(flag1); 46547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_FALSE(flag2); 46647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Force them to run now. 46747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org invoker.Flush(Thread::Current()); 46847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_TRUE(flag1); 46947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_TRUE(flag2); 47047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 47147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 472f46745bdccbac4672fc6fb9b543c4681d0fa7c42kjellander@webrtc.orgTEST_F(AsyncInvokeTest, DISABLED_FlushWithIds) { 47347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org AsyncInvoker invoker; 47447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool flag1 = false; 47547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool flag2 = false; 47647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Queue two async calls to the current thread, one with a message id. 47747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org invoker.AsyncInvoke<void>(Thread::Current(), 47847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org FunctorB(&flag1), 47947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 5); 48047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org invoker.AsyncInvoke<void>(Thread::Current(), 48147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org FunctorB(&flag2)); 48247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Because we haven't pumped messages, these should not have run yet. 48347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_FALSE(flag1); 48447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_FALSE(flag2); 48547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Execute pending calls with id == 5. 48647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org invoker.Flush(Thread::Current(), 5); 48747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_TRUE(flag1); 48847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_FALSE(flag2); 48947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org flag1 = false; 49047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // Execute all pending calls. The id == 5 call should not execute again. 49147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org invoker.Flush(Thread::Current()); 49247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_FALSE(flag1); 49347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_TRUE(flag2); 49447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 49547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 49647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 49747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN) 49847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass ComThreadTest : public testing::Test, public MessageHandler { 49947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public: 50047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org ComThreadTest() : done_(false) {} 50147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org protected: 50247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org virtual void OnMessage(Message* message) { 50347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); 50447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org // S_FALSE means the thread was already inited for a multithread apartment. 50547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_EQ(S_FALSE, hr); 50647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org if (SUCCEEDED(hr)) { 50747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org CoUninitialize(); 50847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 50947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org done_ = true; 51047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org } 51147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org bool done_; 51247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}; 51347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org 51447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgTEST_F(ComThreadTest, ComInited) { 51547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org Thread* thread = new ComThread(); 51647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_TRUE(thread->Start()); 51747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org thread->Post(this, 0); 51847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org EXPECT_TRUE_WAIT(done_, 1000); 51947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org delete thread; 52047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} 52147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif 522