1// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "sandbox/win/src/win2k_threadpool.h"
6#include "testing/gtest/include/gtest/gtest.h"
7
8void __stdcall EmptyCallBack(void*, unsigned char) {
9}
10
11void __stdcall TestCallBack(void* context, unsigned char) {
12  HANDLE event = reinterpret_cast<HANDLE>(context);
13  ::SetEvent(event);
14}
15
16namespace sandbox {
17
18// Test that register and unregister work, part 1.
19TEST(IPCTest, ThreadPoolRegisterTest1) {
20  Win2kThreadPool thread_pool;
21
22  EXPECT_EQ(0, thread_pool.OutstandingWaits());
23
24  HANDLE event1 = ::CreateEventW(NULL, FALSE, FALSE, NULL);
25  HANDLE event2 = ::CreateEventW(NULL, FALSE, FALSE, NULL);
26
27  uint32 context = 0;
28  EXPECT_FALSE(thread_pool.RegisterWait(0, event1, EmptyCallBack, &context));
29  EXPECT_EQ(0, thread_pool.OutstandingWaits());
30
31  EXPECT_TRUE(thread_pool.RegisterWait(this, event1, EmptyCallBack, &context));
32  EXPECT_EQ(1, thread_pool.OutstandingWaits());
33  EXPECT_TRUE(thread_pool.RegisterWait(this, event2, EmptyCallBack, &context));
34  EXPECT_EQ(2, thread_pool.OutstandingWaits());
35
36  EXPECT_TRUE(thread_pool.UnRegisterWaits(this));
37  EXPECT_EQ(0, thread_pool.OutstandingWaits());
38
39  EXPECT_EQ(TRUE, ::CloseHandle(event1));
40  EXPECT_EQ(TRUE, ::CloseHandle(event2));
41}
42
43// Test that register and unregister work, part 2.
44TEST(IPCTest, ThreadPoolRegisterTest2) {
45  Win2kThreadPool thread_pool;
46
47  HANDLE event1 = ::CreateEventW(NULL, FALSE, FALSE, NULL);
48  HANDLE event2 = ::CreateEventW(NULL, FALSE, FALSE, NULL);
49
50  uint32 context = 0;
51  uint32 c1 = 0;
52  uint32 c2 = 0;
53
54  EXPECT_TRUE(thread_pool.RegisterWait(&c1, event1, EmptyCallBack, &context));
55  EXPECT_EQ(1, thread_pool.OutstandingWaits());
56  EXPECT_TRUE(thread_pool.RegisterWait(&c2, event2, EmptyCallBack, &context));
57  EXPECT_EQ(2, thread_pool.OutstandingWaits());
58
59  EXPECT_TRUE(thread_pool.UnRegisterWaits(&c2));
60  EXPECT_EQ(1, thread_pool.OutstandingWaits());
61  EXPECT_TRUE(thread_pool.UnRegisterWaits(&c2));
62  EXPECT_EQ(1, thread_pool.OutstandingWaits());
63
64  EXPECT_TRUE(thread_pool.UnRegisterWaits(&c1));
65  EXPECT_EQ(0, thread_pool.OutstandingWaits());
66
67  EXPECT_EQ(TRUE, ::CloseHandle(event1));
68  EXPECT_EQ(TRUE, ::CloseHandle(event2));
69}
70
71// Test that the thread pool has at least a thread that services an event.
72// Test that when the event is un-registered is no longer serviced.
73TEST(IPCTest, ThreadPoolSignalAndWaitTest) {
74  Win2kThreadPool thread_pool;
75
76  // The events are auto reset and start not signaled.
77  HANDLE event1 = ::CreateEventW(NULL, FALSE, FALSE, NULL);
78  HANDLE event2 = ::CreateEventW(NULL, FALSE, FALSE, NULL);
79
80  EXPECT_TRUE(thread_pool.RegisterWait(this, event1, TestCallBack, event2));
81
82  EXPECT_EQ(WAIT_OBJECT_0, ::SignalObjectAndWait(event1, event2, 5000, FALSE));
83  EXPECT_EQ(WAIT_OBJECT_0, ::SignalObjectAndWait(event1, event2, 5000, FALSE));
84
85  EXPECT_TRUE(thread_pool.UnRegisterWaits(this));
86  EXPECT_EQ(0, thread_pool.OutstandingWaits());
87
88  EXPECT_EQ(WAIT_TIMEOUT, ::SignalObjectAndWait(event1, event2, 1000, FALSE));
89
90  EXPECT_EQ(TRUE, ::CloseHandle(event1));
91  EXPECT_EQ(TRUE, ::CloseHandle(event2));
92}
93
94}  // namespace sandbox
95