1/*
2 * Copyright (C) 2017 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27
28#include <wtf/HashSet.h>
29#include <wtf/Ref.h>
30#include <wtf/ThreadMessage.h>
31#include <wtf/Vector.h>
32
33static void runThreadMessageTest(unsigned numSenders, unsigned numMessages)
34{
35 Atomic<bool> receiverShouldKeepRunning(true);
36 RefPtr<Thread> receiverThread = Thread::create("ThreadMessage receiver", [&receiverShouldKeepRunning] () {
37 while (receiverShouldKeepRunning.load()) { }
38 });
39 ASSERT_TRUE(receiverThread);
40
41 Vector<RefPtr<Thread>> senderThreads(numSenders);
42 Vector<unsigned> messagesRun(numSenders);
43 Vector<unsigned> handlersRun(numSenders);
44 messagesRun.fill(0);
45 handlersRun.fill(0);
46
47 for (unsigned senderID = 0; senderID < numSenders; ++senderID) {
48 senderThreads[senderID] = Thread::create("ThreadMessage sender", [senderID, numMessages, receiverThread, &messagesRun, &handlersRun] () {
49 for (unsigned i = 0; i < numMessages; ++i) {
50 auto result = sendMessage(*receiverThread.get(), [senderID, &handlersRun] (PlatformRegisters&) {
51 handlersRun[senderID]++;
52 });
53 EXPECT_TRUE(result == WTF::MessageStatus::MessageRan);
54 messagesRun[senderID]++;
55 }
56 });
57 ASSERT_TRUE(senderThreads[senderID]);
58 }
59
60 for (unsigned i = 0; i < numSenders; ++i)
61 senderThreads[i]->waitForCompletion();
62
63 receiverShouldKeepRunning.store(false);
64 receiverThread->waitForCompletion();
65
66 for (unsigned i = 0; i < numSenders; ++i) {
67 EXPECT_EQ(numMessages, messagesRun[i]);
68 EXPECT_EQ(numMessages, handlersRun[i]);
69 }
70}
71
72TEST(ThreadMessage, Basic)
73{
74 runThreadMessageTest(1, 1);
75 runThreadMessageTest(1, 100);
76}
77
78TEST(ThreadMessage, MultipleSenders)
79{
80 runThreadMessageTest(10, 1);
81 runThreadMessageTest(10, 100);
82 runThreadMessageTest(10, 10000);
83}
84