1 | //===-- ListenerTest.cpp --------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "gtest/gtest.h" |
10 | |
11 | #include "lldb/Utility/Broadcaster.h" |
12 | #include "lldb/Utility/Listener.h" |
13 | #include <future> |
14 | #include <thread> |
15 | |
16 | using namespace lldb; |
17 | using namespace lldb_private; |
18 | |
19 | TEST(ListenerTest, GetEventImmediate) { |
20 | EventSP event_sp; |
21 | Broadcaster broadcaster(nullptr, "test-broadcaster" ); |
22 | |
23 | // Create a listener, sign it up, make sure it receives an event. |
24 | ListenerSP listener_sp = Listener::MakeListener(name: "test-listener" ); |
25 | const uint32_t event_mask = 1; |
26 | ASSERT_EQ(event_mask, |
27 | listener_sp->StartListeningForEvents(&broadcaster, event_mask)); |
28 | |
29 | const std::chrono::seconds timeout(0); |
30 | // Without any events sent, these should return false. |
31 | EXPECT_FALSE(listener_sp->GetEvent(event_sp, timeout)); |
32 | EXPECT_FALSE(listener_sp->GetEventForBroadcaster(nullptr, event_sp, timeout)); |
33 | EXPECT_FALSE( |
34 | listener_sp->GetEventForBroadcaster(&broadcaster, event_sp, timeout)); |
35 | EXPECT_FALSE(listener_sp->GetEventForBroadcasterWithType( |
36 | &broadcaster, event_mask, event_sp, timeout)); |
37 | |
38 | // Now send events and make sure they get it. |
39 | broadcaster.BroadcastEvent(event_type: event_mask, event_data_sp: nullptr); |
40 | EXPECT_TRUE(listener_sp->GetEvent(event_sp, timeout)); |
41 | |
42 | broadcaster.BroadcastEvent(event_type: event_mask, event_data_sp: nullptr); |
43 | EXPECT_TRUE(listener_sp->GetEventForBroadcaster(nullptr, event_sp, timeout)); |
44 | |
45 | broadcaster.BroadcastEvent(event_type: event_mask, event_data_sp: nullptr); |
46 | EXPECT_TRUE( |
47 | listener_sp->GetEventForBroadcaster(&broadcaster, event_sp, timeout)); |
48 | |
49 | broadcaster.BroadcastEvent(event_type: event_mask, event_data_sp: nullptr); |
50 | EXPECT_FALSE(listener_sp->GetEventForBroadcasterWithType( |
51 | &broadcaster, event_mask * 2, event_sp, timeout)); |
52 | EXPECT_TRUE(listener_sp->GetEventForBroadcasterWithType( |
53 | &broadcaster, event_mask, event_sp, timeout)); |
54 | } |
55 | |
56 | TEST(ListenerTest, GetEventWait) { |
57 | EventSP event_sp; |
58 | Broadcaster broadcaster(nullptr, "test-broadcaster" ); |
59 | |
60 | // Create a listener, sign it up, make sure it receives an event. |
61 | ListenerSP listener_sp = Listener::MakeListener(name: "test-listener" ); |
62 | const uint32_t event_mask = 1; |
63 | ASSERT_EQ(event_mask, |
64 | listener_sp->StartListeningForEvents(&broadcaster, event_mask)); |
65 | |
66 | // Without any events sent, these should make a short wait and return false. |
67 | std::chrono::microseconds timeout(10); |
68 | EXPECT_FALSE(listener_sp->GetEvent(event_sp, timeout)); |
69 | EXPECT_FALSE(listener_sp->GetEventForBroadcaster(nullptr, event_sp, timeout)); |
70 | EXPECT_FALSE( |
71 | listener_sp->GetEventForBroadcaster(&broadcaster, event_sp, timeout)); |
72 | EXPECT_FALSE(listener_sp->GetEventForBroadcasterWithType( |
73 | &broadcaster, event_mask, event_sp, timeout)); |
74 | |
75 | // Now send events and make sure they get it. |
76 | broadcaster.BroadcastEvent(event_type: event_mask, event_data_sp: nullptr); |
77 | EXPECT_TRUE(listener_sp->GetEvent(event_sp, timeout)); |
78 | |
79 | broadcaster.BroadcastEvent(event_type: event_mask, event_data_sp: nullptr); |
80 | EXPECT_TRUE(listener_sp->GetEventForBroadcaster(nullptr, event_sp, timeout)); |
81 | |
82 | broadcaster.BroadcastEvent(event_type: event_mask, event_data_sp: nullptr); |
83 | EXPECT_TRUE( |
84 | listener_sp->GetEventForBroadcaster(&broadcaster, event_sp, timeout)); |
85 | |
86 | broadcaster.BroadcastEvent(event_type: event_mask, event_data_sp: nullptr); |
87 | EXPECT_FALSE(listener_sp->GetEventForBroadcasterWithType( |
88 | &broadcaster, event_mask * 2, event_sp, timeout)); |
89 | EXPECT_TRUE(listener_sp->GetEventForBroadcasterWithType( |
90 | &broadcaster, event_mask, event_sp, timeout)); |
91 | |
92 | auto delayed_broadcast = [&] { |
93 | std::this_thread::sleep_for(rtime: std::chrono::milliseconds(10)); |
94 | broadcaster.BroadcastEvent(event_type: event_mask, event_data_sp: nullptr); |
95 | }; |
96 | |
97 | // These should do an infinite wait at return the event our asynchronous |
98 | // broadcast sends. |
99 | std::future<void> async_broadcast = |
100 | std::async(policy: std::launch::async, fn&: delayed_broadcast); |
101 | EXPECT_TRUE(listener_sp->GetEvent(event_sp, std::nullopt)); |
102 | async_broadcast.get(); |
103 | |
104 | async_broadcast = std::async(policy: std::launch::async, fn&: delayed_broadcast); |
105 | EXPECT_TRUE(listener_sp->GetEventForBroadcaster(&broadcaster, event_sp, |
106 | std::nullopt)); |
107 | async_broadcast.get(); |
108 | |
109 | async_broadcast = std::async(policy: std::launch::async, fn&: delayed_broadcast); |
110 | EXPECT_TRUE(listener_sp->GetEventForBroadcasterWithType( |
111 | &broadcaster, event_mask, event_sp, std::nullopt)); |
112 | async_broadcast.get(); |
113 | } |
114 | |