1 /*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include <signal.h>
12 #include <stdarg.h>
13
14 #include "webrtc/base/gunit.h"
15 #include "webrtc/base/logging.h"
16 #include "webrtc/base/physicalsocketserver.h"
17 #include "webrtc/base/scoped_ptr.h"
18 #include "webrtc/base/socket_unittest.h"
19 #include "webrtc/base/testutils.h"
20 #include "webrtc/base/thread.h"
21
22 namespace rtc {
23
24 class PhysicalSocketTest;
25
26 class FakeSocketDispatcher : public SocketDispatcher {
27 public:
FakeSocketDispatcher(PhysicalSocketServer * ss)28 explicit FakeSocketDispatcher(PhysicalSocketServer* ss)
29 : SocketDispatcher(ss) {
30 }
31
32 protected:
33 SOCKET DoAccept(SOCKET socket, sockaddr* addr, socklen_t* addrlen) override;
34 };
35
36 class FakePhysicalSocketServer : public PhysicalSocketServer {
37 public:
FakePhysicalSocketServer(PhysicalSocketTest * test)38 explicit FakePhysicalSocketServer(PhysicalSocketTest* test)
39 : test_(test) {
40 }
41
CreateAsyncSocket(int type)42 AsyncSocket* CreateAsyncSocket(int type) override {
43 SocketDispatcher* dispatcher = new FakeSocketDispatcher(this);
44 if (dispatcher->Create(type)) {
45 return dispatcher;
46 } else {
47 delete dispatcher;
48 return nullptr;
49 }
50 }
51
CreateAsyncSocket(int family,int type)52 AsyncSocket* CreateAsyncSocket(int family, int type) override {
53 SocketDispatcher* dispatcher = new FakeSocketDispatcher(this);
54 if (dispatcher->Create(family, type)) {
55 return dispatcher;
56 } else {
57 delete dispatcher;
58 return nullptr;
59 }
60 }
61
GetTest() const62 PhysicalSocketTest* GetTest() const { return test_; }
63
64 private:
65 PhysicalSocketTest* test_;
66 };
67
68 class PhysicalSocketTest : public SocketTest {
69 public:
70 // Set flag to simluate failures when calling "::accept" on a AsyncSocket.
SetFailAccept(bool fail)71 void SetFailAccept(bool fail) { fail_accept_ = fail; }
FailAccept() const72 bool FailAccept() const { return fail_accept_; }
73
74 protected:
PhysicalSocketTest()75 PhysicalSocketTest()
76 : server_(new FakePhysicalSocketServer(this)),
77 scope_(server_.get()),
78 fail_accept_(false) {
79 }
80
81 void ConnectInternalAcceptError(const IPAddress& loopback);
82
83 rtc::scoped_ptr<FakePhysicalSocketServer> server_;
84 SocketServerScope scope_;
85 bool fail_accept_;
86 };
87
DoAccept(SOCKET socket,sockaddr * addr,socklen_t * addrlen)88 SOCKET FakeSocketDispatcher::DoAccept(SOCKET socket,
89 sockaddr* addr,
90 socklen_t* addrlen) {
91 FakePhysicalSocketServer* ss =
92 static_cast<FakePhysicalSocketServer*>(socketserver());
93 if (ss->GetTest()->FailAccept()) {
94 return INVALID_SOCKET;
95 }
96
97 return SocketDispatcher::DoAccept(socket, addr, addrlen);
98 }
99
TEST_F(PhysicalSocketTest,TestConnectIPv4)100 TEST_F(PhysicalSocketTest, TestConnectIPv4) {
101 SocketTest::TestConnectIPv4();
102 }
103
104 // Crashes on Linux. See webrtc:4923.
105 #if defined(WEBRTC_LINUX)
106 #define MAYBE_TestConnectIPv6 DISABLED_TestConnectIPv6
107 #else
108 #define MAYBE_TestConnectIPv6 TestConnectIPv6
109 #endif
TEST_F(PhysicalSocketTest,MAYBE_TestConnectIPv6)110 TEST_F(PhysicalSocketTest, MAYBE_TestConnectIPv6) {
111 SocketTest::TestConnectIPv6();
112 }
113
TEST_F(PhysicalSocketTest,TestConnectWithDnsLookupIPv4)114 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv4) {
115 SocketTest::TestConnectWithDnsLookupIPv4();
116 }
117
TEST_F(PhysicalSocketTest,TestConnectWithDnsLookupIPv6)118 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupIPv6) {
119 SocketTest::TestConnectWithDnsLookupIPv6();
120 }
121
TEST_F(PhysicalSocketTest,TestConnectFailIPv4)122 TEST_F(PhysicalSocketTest, TestConnectFailIPv4) {
123 SocketTest::TestConnectFailIPv4();
124 }
125
ConnectInternalAcceptError(const IPAddress & loopback)126 void PhysicalSocketTest::ConnectInternalAcceptError(const IPAddress& loopback) {
127 testing::StreamSink sink;
128 SocketAddress accept_addr;
129
130 // Create two clients.
131 scoped_ptr<AsyncSocket> client1(server_->CreateAsyncSocket(loopback.family(),
132 SOCK_STREAM));
133 sink.Monitor(client1.get());
134 EXPECT_EQ(AsyncSocket::CS_CLOSED, client1->GetState());
135 EXPECT_PRED1(IsUnspecOrEmptyIP, client1->GetLocalAddress().ipaddr());
136
137 scoped_ptr<AsyncSocket> client2(server_->CreateAsyncSocket(loopback.family(),
138 SOCK_STREAM));
139 sink.Monitor(client2.get());
140 EXPECT_EQ(AsyncSocket::CS_CLOSED, client2->GetState());
141 EXPECT_PRED1(IsUnspecOrEmptyIP, client2->GetLocalAddress().ipaddr());
142
143 // Create server and listen.
144 scoped_ptr<AsyncSocket> server(
145 server_->CreateAsyncSocket(loopback.family(), SOCK_STREAM));
146 sink.Monitor(server.get());
147 EXPECT_EQ(0, server->Bind(SocketAddress(loopback, 0)));
148 EXPECT_EQ(0, server->Listen(5));
149 EXPECT_EQ(AsyncSocket::CS_CONNECTING, server->GetState());
150
151 // Ensure no pending server connections, since we haven't done anything yet.
152 EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
153 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
154 EXPECT_TRUE(accept_addr.IsNil());
155
156 // Attempt first connect to listening socket.
157 EXPECT_EQ(0, client1->Connect(server->GetLocalAddress()));
158 EXPECT_FALSE(client1->GetLocalAddress().IsNil());
159 EXPECT_NE(server->GetLocalAddress(), client1->GetLocalAddress());
160
161 // Client is connecting, outcome not yet determined.
162 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client1->GetState());
163 EXPECT_FALSE(sink.Check(client1.get(), testing::SSE_OPEN));
164 EXPECT_FALSE(sink.Check(client1.get(), testing::SSE_CLOSE));
165
166 // Server has pending connection, try to accept it (will fail).
167 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
168 // Simulate "::accept" returning an error.
169 SetFailAccept(true);
170 scoped_ptr<AsyncSocket> accepted(server->Accept(&accept_addr));
171 EXPECT_FALSE(accepted);
172 ASSERT_TRUE(accept_addr.IsNil());
173
174 // Ensure no more pending server connections.
175 EXPECT_FALSE(sink.Check(server.get(), testing::SSE_READ));
176 EXPECT_TRUE(nullptr == server->Accept(&accept_addr));
177 EXPECT_TRUE(accept_addr.IsNil());
178
179 // Attempt second connect to listening socket.
180 EXPECT_EQ(0, client2->Connect(server->GetLocalAddress()));
181 EXPECT_FALSE(client2->GetLocalAddress().IsNil());
182 EXPECT_NE(server->GetLocalAddress(), client2->GetLocalAddress());
183
184 // Client is connecting, outcome not yet determined.
185 EXPECT_EQ(AsyncSocket::CS_CONNECTING, client2->GetState());
186 EXPECT_FALSE(sink.Check(client2.get(), testing::SSE_OPEN));
187 EXPECT_FALSE(sink.Check(client2.get(), testing::SSE_CLOSE));
188
189 // Server has pending connection, try to accept it (will succeed).
190 EXPECT_TRUE_WAIT((sink.Check(server.get(), testing::SSE_READ)), kTimeout);
191 SetFailAccept(false);
192 scoped_ptr<AsyncSocket> accepted2(server->Accept(&accept_addr));
193 ASSERT_TRUE(accepted2);
194 EXPECT_FALSE(accept_addr.IsNil());
195 EXPECT_EQ(accepted2->GetRemoteAddress(), accept_addr);
196 }
197
TEST_F(PhysicalSocketTest,TestConnectAcceptErrorIPv4)198 TEST_F(PhysicalSocketTest, TestConnectAcceptErrorIPv4) {
199 ConnectInternalAcceptError(kIPv4Loopback);
200 }
201
202 // Crashes on Linux. See webrtc:4923.
203 #if defined(WEBRTC_LINUX)
204 #define MAYBE_TestConnectAcceptErrorIPv6 DISABLED_TestConnectAcceptErrorIPv6
205 #else
206 #define MAYBE_TestConnectAcceptErrorIPv6 TestConnectAcceptErrorIPv6
207 #endif
TEST_F(PhysicalSocketTest,MAYBE_TestConnectAcceptErrorIPv6)208 TEST_F(PhysicalSocketTest, MAYBE_TestConnectAcceptErrorIPv6) {
209 ConnectInternalAcceptError(kIPv6Loopback);
210 }
211
212 // Crashes on Linux. See webrtc:4923.
213 #if defined(WEBRTC_LINUX)
214 #define MAYBE_TestConnectFailIPv6 DISABLED_TestConnectFailIPv6
215 #else
216 #define MAYBE_TestConnectFailIPv6 TestConnectFailIPv6
217 #endif
TEST_F(PhysicalSocketTest,MAYBE_TestConnectFailIPv6)218 TEST_F(PhysicalSocketTest, MAYBE_TestConnectFailIPv6) {
219 SocketTest::TestConnectFailIPv6();
220 }
221
TEST_F(PhysicalSocketTest,TestConnectWithDnsLookupFailIPv4)222 TEST_F(PhysicalSocketTest, TestConnectWithDnsLookupFailIPv4) {
223 SocketTest::TestConnectWithDnsLookupFailIPv4();
224 }
225
226 // Crashes on Linux. See webrtc:4923.
227 #if defined(WEBRTC_LINUX)
228 #define MAYBE_TestConnectWithDnsLookupFailIPv6 \
229 DISABLED_TestConnectWithDnsLookupFailIPv6
230 #else
231 #define MAYBE_TestConnectWithDnsLookupFailIPv6 \
232 TestConnectWithDnsLookupFailIPv6
233 #endif
TEST_F(PhysicalSocketTest,MAYBE_TestConnectWithDnsLookupFailIPv6)234 TEST_F(PhysicalSocketTest, MAYBE_TestConnectWithDnsLookupFailIPv6) {
235 SocketTest::TestConnectWithDnsLookupFailIPv6();
236 }
237
238
TEST_F(PhysicalSocketTest,TestConnectWithClosedSocketIPv4)239 TEST_F(PhysicalSocketTest, TestConnectWithClosedSocketIPv4) {
240 SocketTest::TestConnectWithClosedSocketIPv4();
241 }
242
243 // Crashes on Linux. See webrtc:4923.
244 #if defined(WEBRTC_LINUX)
245 #define MAYBE_TestConnectWithClosedSocketIPv6 \
246 DISABLED_TestConnectWithClosedSocketIPv6
247 #else
248 #define MAYBE_TestConnectWithClosedSocketIPv6 TestConnectWithClosedSocketIPv6
249 #endif
TEST_F(PhysicalSocketTest,MAYBE_TestConnectWithClosedSocketIPv6)250 TEST_F(PhysicalSocketTest, MAYBE_TestConnectWithClosedSocketIPv6) {
251 SocketTest::TestConnectWithClosedSocketIPv6();
252 }
253
TEST_F(PhysicalSocketTest,TestConnectWhileNotClosedIPv4)254 TEST_F(PhysicalSocketTest, TestConnectWhileNotClosedIPv4) {
255 SocketTest::TestConnectWhileNotClosedIPv4();
256 }
257
258 // Crashes on Linux. See webrtc:4923.
259 #if defined(WEBRTC_LINUX)
260 #define MAYBE_TestConnectWhileNotClosedIPv6 \
261 DISABLED_TestConnectWhileNotClosedIPv6
262 #else
263 #define MAYBE_TestConnectWhileNotClosedIPv6 TestConnectWhileNotClosedIPv6
264 #endif
TEST_F(PhysicalSocketTest,MAYBE_TestConnectWhileNotClosedIPv6)265 TEST_F(PhysicalSocketTest, MAYBE_TestConnectWhileNotClosedIPv6) {
266 SocketTest::TestConnectWhileNotClosedIPv6();
267 }
268
TEST_F(PhysicalSocketTest,TestServerCloseDuringConnectIPv4)269 TEST_F(PhysicalSocketTest, TestServerCloseDuringConnectIPv4) {
270 SocketTest::TestServerCloseDuringConnectIPv4();
271 }
272
273 // Crashes on Linux. See webrtc:4923.
274 #if defined(WEBRTC_LINUX)
275 #define MAYBE_TestServerCloseDuringConnectIPv6 \
276 DISABLED_TestServerCloseDuringConnectIPv6
277 #else
278 #define MAYBE_TestServerCloseDuringConnectIPv6 TestServerCloseDuringConnectIPv6
279 #endif
TEST_F(PhysicalSocketTest,MAYBE_TestServerCloseDuringConnectIPv6)280 TEST_F(PhysicalSocketTest, MAYBE_TestServerCloseDuringConnectIPv6) {
281 SocketTest::TestServerCloseDuringConnectIPv6();
282 }
283
TEST_F(PhysicalSocketTest,TestClientCloseDuringConnectIPv4)284 TEST_F(PhysicalSocketTest, TestClientCloseDuringConnectIPv4) {
285 SocketTest::TestClientCloseDuringConnectIPv4();
286 }
287
288 // Crashes on Linux. See webrtc:4923.
289 #if defined(WEBRTC_LINUX)
290 #define MAYBE_TestClientCloseDuringConnectIPv6 \
291 DISABLED_TestClientCloseDuringConnectIPv6
292 #else
293 #define MAYBE_TestClientCloseDuringConnectIPv6 TestClientCloseDuringConnectIPv6
294 #endif
TEST_F(PhysicalSocketTest,MAYBE_TestClientCloseDuringConnectIPv6)295 TEST_F(PhysicalSocketTest, MAYBE_TestClientCloseDuringConnectIPv6) {
296 SocketTest::TestClientCloseDuringConnectIPv6();
297 }
298
TEST_F(PhysicalSocketTest,TestServerCloseIPv4)299 TEST_F(PhysicalSocketTest, TestServerCloseIPv4) {
300 SocketTest::TestServerCloseIPv4();
301 }
302
303 // Crashes on Linux. See webrtc:4923.
304 #if defined(WEBRTC_LINUX)
305 #define MAYBE_TestServerCloseIPv6 DISABLED_TestServerCloseIPv6
306 #else
307 #define MAYBE_TestServerCloseIPv6 TestServerCloseIPv6
308 #endif
TEST_F(PhysicalSocketTest,MAYBE_TestServerCloseIPv6)309 TEST_F(PhysicalSocketTest, MAYBE_TestServerCloseIPv6) {
310 SocketTest::TestServerCloseIPv6();
311 }
312
TEST_F(PhysicalSocketTest,TestCloseInClosedCallbackIPv4)313 TEST_F(PhysicalSocketTest, TestCloseInClosedCallbackIPv4) {
314 SocketTest::TestCloseInClosedCallbackIPv4();
315 }
316
317 // Crashes on Linux. See webrtc:4923.
318 #if defined(WEBRTC_LINUX)
319 #define MAYBE_TestCloseInClosedCallbackIPv6 \
320 DISABLED_TestCloseInClosedCallbackIPv6
321 #else
322 #define MAYBE_TestCloseInClosedCallbackIPv6 TestCloseInClosedCallbackIPv6
323 #endif
TEST_F(PhysicalSocketTest,MAYBE_TestCloseInClosedCallbackIPv6)324 TEST_F(PhysicalSocketTest, MAYBE_TestCloseInClosedCallbackIPv6) {
325 SocketTest::TestCloseInClosedCallbackIPv6();
326 }
327
TEST_F(PhysicalSocketTest,TestSocketServerWaitIPv4)328 TEST_F(PhysicalSocketTest, TestSocketServerWaitIPv4) {
329 SocketTest::TestSocketServerWaitIPv4();
330 }
331
332 // Crashes on Linux. See webrtc:4923.
333 #if defined(WEBRTC_LINUX)
334 #define MAYBE_TestSocketServerWaitIPv6 DISABLED_TestSocketServerWaitIPv6
335 #else
336 #define MAYBE_TestSocketServerWaitIPv6 TestSocketServerWaitIPv6
337 #endif
TEST_F(PhysicalSocketTest,MAYBE_TestSocketServerWaitIPv6)338 TEST_F(PhysicalSocketTest, MAYBE_TestSocketServerWaitIPv6) {
339 SocketTest::TestSocketServerWaitIPv6();
340 }
341
TEST_F(PhysicalSocketTest,TestTcpIPv4)342 TEST_F(PhysicalSocketTest, TestTcpIPv4) {
343 SocketTest::TestTcpIPv4();
344 }
345
346 // Crashes on Linux. See webrtc:4923.
347 #if defined(WEBRTC_LINUX)
348 #define MAYBE_TestTcpIPv6 DISABLED_TestTcpIPv6
349 #else
350 #define MAYBE_TestTcpIPv6 TestTcpIPv6
351 #endif
TEST_F(PhysicalSocketTest,MAYBE_TestTcpIPv6)352 TEST_F(PhysicalSocketTest, MAYBE_TestTcpIPv6) {
353 SocketTest::TestTcpIPv6();
354 }
355
TEST_F(PhysicalSocketTest,TestUdpIPv4)356 TEST_F(PhysicalSocketTest, TestUdpIPv4) {
357 SocketTest::TestUdpIPv4();
358 }
359
360 // Crashes on Linux. See webrtc:4923.
361 #if defined(WEBRTC_LINUX)
362 #define MAYBE_TestUdpIPv6 DISABLED_TestUdpIPv6
363 #else
364 #define MAYBE_TestUdpIPv6 TestUdpIPv6
365 #endif
TEST_F(PhysicalSocketTest,MAYBE_TestUdpIPv6)366 TEST_F(PhysicalSocketTest, MAYBE_TestUdpIPv6) {
367 SocketTest::TestUdpIPv6();
368 }
369
370 // Disable for TSan v2, see
371 // https://code.google.com/p/webrtc/issues/detail?id=3498 for details.
372 // Also disable for MSan, see:
373 // https://code.google.com/p/webrtc/issues/detail?id=4958
374 // TODO(deadbeef): Enable again once test is reimplemented to be unflaky.
375 // Also disable for ASan.
376 // Disabled on Android: https://code.google.com/p/webrtc/issues/detail?id=4364
377 // Disabled on Linux: https://bugs.chromium.org/p/webrtc/issues/detail?id=5233
378 #if defined(THREAD_SANITIZER) || defined(MEMORY_SANITIZER) || \
379 defined(ADDRESS_SANITIZER) || defined(WEBRTC_ANDROID) || \
380 defined(WEBRTC_LINUX)
381 #define MAYBE_TestUdpReadyToSendIPv4 DISABLED_TestUdpReadyToSendIPv4
382 #else
383 #define MAYBE_TestUdpReadyToSendIPv4 TestUdpReadyToSendIPv4
384 #endif
TEST_F(PhysicalSocketTest,MAYBE_TestUdpReadyToSendIPv4)385 TEST_F(PhysicalSocketTest, MAYBE_TestUdpReadyToSendIPv4) {
386 SocketTest::TestUdpReadyToSendIPv4();
387 }
388
TEST_F(PhysicalSocketTest,TestUdpReadyToSendIPv6)389 TEST_F(PhysicalSocketTest, TestUdpReadyToSendIPv6) {
390 SocketTest::TestUdpReadyToSendIPv6();
391 }
392
TEST_F(PhysicalSocketTest,TestGetSetOptionsIPv4)393 TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv4) {
394 SocketTest::TestGetSetOptionsIPv4();
395 }
396
TEST_F(PhysicalSocketTest,TestGetSetOptionsIPv6)397 TEST_F(PhysicalSocketTest, TestGetSetOptionsIPv6) {
398 SocketTest::TestGetSetOptionsIPv6();
399 }
400
401 #if defined(WEBRTC_POSIX)
402
403 class PosixSignalDeliveryTest : public testing::Test {
404 public:
RecordSignal(int signum)405 static void RecordSignal(int signum) {
406 signals_received_.push_back(signum);
407 signaled_thread_ = Thread::Current();
408 }
409
410 protected:
SetUp()411 void SetUp() {
412 ss_.reset(new PhysicalSocketServer());
413 }
414
TearDown()415 void TearDown() {
416 ss_.reset(NULL);
417 signals_received_.clear();
418 signaled_thread_ = NULL;
419 }
420
ExpectSignal(int signum)421 bool ExpectSignal(int signum) {
422 if (signals_received_.empty()) {
423 LOG(LS_ERROR) << "ExpectSignal(): No signal received";
424 return false;
425 }
426 if (signals_received_[0] != signum) {
427 LOG(LS_ERROR) << "ExpectSignal(): Received signal " <<
428 signals_received_[0] << ", expected " << signum;
429 return false;
430 }
431 signals_received_.erase(signals_received_.begin());
432 return true;
433 }
434
ExpectNone()435 bool ExpectNone() {
436 bool ret = signals_received_.empty();
437 if (!ret) {
438 LOG(LS_ERROR) << "ExpectNone(): Received signal " << signals_received_[0]
439 << ", expected none";
440 }
441 return ret;
442 }
443
444 static std::vector<int> signals_received_;
445 static Thread *signaled_thread_;
446
447 scoped_ptr<PhysicalSocketServer> ss_;
448 };
449
450 std::vector<int> PosixSignalDeliveryTest::signals_received_;
451 Thread *PosixSignalDeliveryTest::signaled_thread_ = NULL;
452
453 // Test receiving a synchronous signal while not in Wait() and then entering
454 // Wait() afterwards.
TEST_F(PosixSignalDeliveryTest,RaiseThenWait)455 TEST_F(PosixSignalDeliveryTest, RaiseThenWait) {
456 ASSERT_TRUE(ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal));
457 raise(SIGTERM);
458 EXPECT_TRUE(ss_->Wait(0, true));
459 EXPECT_TRUE(ExpectSignal(SIGTERM));
460 EXPECT_TRUE(ExpectNone());
461 }
462
463 // Test that we can handle getting tons of repeated signals and that we see all
464 // the different ones.
TEST_F(PosixSignalDeliveryTest,InsanelyManySignals)465 TEST_F(PosixSignalDeliveryTest, InsanelyManySignals) {
466 ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
467 ss_->SetPosixSignalHandler(SIGINT, &RecordSignal);
468 for (int i = 0; i < 10000; ++i) {
469 raise(SIGTERM);
470 }
471 raise(SIGINT);
472 EXPECT_TRUE(ss_->Wait(0, true));
473 // Order will be lowest signal numbers first.
474 EXPECT_TRUE(ExpectSignal(SIGINT));
475 EXPECT_TRUE(ExpectSignal(SIGTERM));
476 EXPECT_TRUE(ExpectNone());
477 }
478
479 // Test that a signal during a Wait() call is detected.
TEST_F(PosixSignalDeliveryTest,SignalDuringWait)480 TEST_F(PosixSignalDeliveryTest, SignalDuringWait) {
481 ss_->SetPosixSignalHandler(SIGALRM, &RecordSignal);
482 alarm(1);
483 EXPECT_TRUE(ss_->Wait(1500, true));
484 EXPECT_TRUE(ExpectSignal(SIGALRM));
485 EXPECT_TRUE(ExpectNone());
486 }
487
488 class RaiseSigTermRunnable : public Runnable {
Run(Thread * thread)489 void Run(Thread *thread) {
490 thread->socketserver()->Wait(1000, false);
491
492 // Allow SIGTERM. This will be the only thread with it not masked so it will
493 // be delivered to us.
494 sigset_t mask;
495 sigemptyset(&mask);
496 pthread_sigmask(SIG_SETMASK, &mask, NULL);
497
498 // Raise it.
499 raise(SIGTERM);
500 }
501 };
502
503 // Test that it works no matter what thread the kernel chooses to give the
504 // signal to (since it's not guaranteed to be the one that Wait() runs on).
TEST_F(PosixSignalDeliveryTest,SignalOnDifferentThread)505 TEST_F(PosixSignalDeliveryTest, SignalOnDifferentThread) {
506 ss_->SetPosixSignalHandler(SIGTERM, &RecordSignal);
507 // Mask out SIGTERM so that it can't be delivered to this thread.
508 sigset_t mask;
509 sigemptyset(&mask);
510 sigaddset(&mask, SIGTERM);
511 EXPECT_EQ(0, pthread_sigmask(SIG_SETMASK, &mask, NULL));
512 // Start a new thread that raises it. It will have to be delivered to that
513 // thread. Our implementation should safely handle it and dispatch
514 // RecordSignal() on this thread.
515 scoped_ptr<Thread> thread(new Thread());
516 scoped_ptr<RaiseSigTermRunnable> runnable(new RaiseSigTermRunnable());
517 thread->Start(runnable.get());
518 EXPECT_TRUE(ss_->Wait(1500, true));
519 EXPECT_TRUE(ExpectSignal(SIGTERM));
520 EXPECT_EQ(Thread::Current(), signaled_thread_);
521 EXPECT_TRUE(ExpectNone());
522 }
523
524 #endif
525
526 } // namespace rtc
527