3 * Copyright 2004--2011, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include "talk/base/asyncudpsocket.h"
29 #include "talk/base/event.h"
30 #include "talk/base/gunit.h"
31 #include "talk/base/physicalsocketserver.h"
32 #include "talk/base/socketaddress.h"
33 #include "talk/base/thread.h"
36 #include <comdef.h> // NOLINT
39 using namespace talk_base;
41 const int MAX = 65536;
43 // Generates a sequence of numbers (collaboratively).
46 TestGenerator() : last(0), count(0) {}
49 int result = prev + last;
59 struct TestMessage : public MessageData {
60 explicit TestMessage(int v) : value(v) {}
61 virtual ~TestMessage() {}
66 // Receives on a socket and sends by posting messages.
67 class SocketClient : public TestGenerator, public sigslot::has_slots<> {
69 SocketClient(AsyncSocket* socket, const SocketAddress& addr,
70 Thread* post_thread, MessageHandler* phandler)
71 : socket_(AsyncUDPSocket::Create(socket, addr)),
72 post_thread_(post_thread),
73 post_handler_(phandler) {
74 socket_->SignalReadPacket.connect(this, &SocketClient::OnPacket);
81 SocketAddress address() const { return socket_->GetLocalAddress(); }
83 void OnPacket(AsyncPacketSocket* socket, const char* buf, size_t size,
84 const SocketAddress& remote_addr) {
85 EXPECT_EQ(size, sizeof(uint32));
86 uint32 prev = reinterpret_cast<const uint32*>(buf)[0];
87 uint32 result = Next(prev);
89 //socket_->set_readable(last < MAX);
90 post_thread_->PostDelayed(200, post_handler_, 0, new TestMessage(result));
94 AsyncUDPSocket* socket_;
96 MessageHandler* post_handler_;
99 // Receives messages and sends on a socket.
100 class MessageClient : public MessageHandler, public TestGenerator {
102 MessageClient(Thread* pth, Socket* socket)
103 : thread_(pth), socket_(socket) {
106 virtual ~MessageClient() {
110 virtual void OnMessage(Message *pmsg) {
111 TestMessage* msg = static_cast<TestMessage*>(pmsg->pdata);
112 int result = Next(msg->value);
113 EXPECT_GE(socket_->Send(&result, sizeof(result)), 0);
122 class CustomThread : public talk_base::Thread {
125 virtual ~CustomThread() { Stop(); }
126 bool Start() { return false; }
130 // A thread that does nothing when it runs and signals an event
131 // when it is destroyed.
132 class SignalWhenDestroyedThread : public Thread {
134 SignalWhenDestroyedThread(Event* event)
138 virtual ~SignalWhenDestroyedThread() {
151 // Function objects to test Thread::Invoke.
153 int operator()() { return 42; }
157 explicit Functor2(bool* flag) : flag_(flag) {}
158 void operator()() { if (flag_) *flag_ = true; }
163 // See: https://code.google.com/p/webrtc/issues/detail?id=2409
164 TEST(ThreadTest, DISABLED_Main) {
165 const SocketAddress addr("127.0.0.1", 0);
167 // Create the messaging client on its own thread.
169 Socket* socket = th1.socketserver()->CreateAsyncSocket(addr.family(),
171 MessageClient msg_client(&th1, socket);
173 // Create the socket client on its own thread.
175 AsyncSocket* asocket =
176 th2.socketserver()->CreateAsyncSocket(addr.family(), SOCK_DGRAM);
177 SocketClient sock_client(asocket, addr, &th1, &msg_client);
179 socket->Connect(sock_client.address());
184 // Get the messages started.
185 th1.PostDelayed(100, &msg_client, 0, new TestMessage(1));
187 // Give the clients a little while to run.
188 // Messages will be processed at 100, 300, 500, 700, 900.
189 Thread* th_main = Thread::Current();
190 th_main->ProcessMessages(1000);
192 // Stop the sending client. Give the receiver a bit longer to run, in case
193 // it is running on a machine that is under load (e.g. the build machine).
195 th_main->ProcessMessages(200);
198 // Make sure the results were correct
199 EXPECT_EQ(5, msg_client.count);
200 EXPECT_EQ(34, msg_client.last);
201 EXPECT_EQ(5, sock_client.count);
202 EXPECT_EQ(55, sock_client.last);
205 // Test that setting thread names doesn't cause a malfunction.
206 // There's no easy way to verify the name was set properly at this time.
207 TEST(ThreadTest, Names) {
210 thread = new Thread();
211 EXPECT_TRUE(thread->Start());
214 thread = new Thread();
215 // Name with no object parameter
216 EXPECT_TRUE(thread->SetName("No object", NULL));
217 EXPECT_TRUE(thread->Start());
221 thread = new Thread();
222 EXPECT_TRUE(thread->SetName("Abcdefghijklmnopqrstuvwxyz1234567890", this));
223 EXPECT_TRUE(thread->Start());
228 // Test that setting thread priorities doesn't cause a malfunction.
229 // There's no easy way to verify the priority was set properly at this time.
230 TEST(ThreadTest, Priorities) {
232 thread = new Thread();
233 EXPECT_TRUE(thread->SetPriority(PRIORITY_HIGH));
234 EXPECT_TRUE(thread->Start());
237 thread = new Thread();
238 EXPECT_TRUE(thread->SetPriority(PRIORITY_ABOVE_NORMAL));
239 EXPECT_TRUE(thread->Start());
243 thread = new Thread();
244 EXPECT_TRUE(thread->Start());
246 EXPECT_TRUE(thread->SetPriority(PRIORITY_ABOVE_NORMAL));
248 EXPECT_FALSE(thread->SetPriority(PRIORITY_ABOVE_NORMAL));
255 TEST(ThreadTest, Wrap) {
256 Thread* current_thread = Thread::Current();
257 current_thread->UnwrapCurrent();
258 CustomThread* cthread = new CustomThread();
259 EXPECT_TRUE(cthread->WrapCurrent());
260 EXPECT_TRUE(cthread->started());
261 EXPECT_FALSE(cthread->IsOwned());
262 cthread->UnwrapCurrent();
263 EXPECT_FALSE(cthread->started());
265 current_thread->WrapCurrent();
268 // Test that calling Release on a thread causes it to self-destruct when
269 // it's finished running
270 TEST(ThreadTest, Release) {
271 scoped_ptr<Event> event(new Event(true, false));
272 // Ensure the event is initialized.
275 Thread* thread = new SignalWhenDestroyedThread(event.get());
279 // The event should get signaled when the thread completes, which should
280 // be nearly instantaneous, since it doesn't do anything. For safety,
281 // give it 3 seconds in case the machine is under load.
282 bool signaled = event->Wait(3000);
283 EXPECT_TRUE(signaled);
286 TEST(ThreadTest, Invoke) {
287 // Create and start the thread.
290 // Try calling functors.
291 EXPECT_EQ(42, thread.Invoke<int>(Functor1()));
293 Functor2 f2(&called);
294 thread.Invoke<void>(f2);
296 // Try calling bare functions.
298 static int Func1() { return 999; }
299 static void Func2() {}
301 EXPECT_EQ(999, thread.Invoke<int>(&LocalFuncs::Func1));
302 thread.Invoke<void>(&LocalFuncs::Func2);
306 class ComThreadTest : public testing::Test, public MessageHandler {
308 ComThreadTest() : done_(false) {}
310 virtual void OnMessage(Message* message) {
311 HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
312 // S_FALSE means the thread was already inited for a multithread apartment.
313 EXPECT_EQ(S_FALSE, hr);
322 TEST_F(ComThreadTest, ComInited) {
323 Thread* thread = new ComThread();
324 EXPECT_TRUE(thread->Start());
325 thread->Post(this, 0);
326 EXPECT_TRUE_WAIT(done_, 1000);