xref: /llvm-project/lldb/unittests/Utility/ListenerTest.cpp (revision 2a14c0643597c5932af85f22172c99800f9b4a6c)
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/Event.h"
13 #include "lldb/Utility/Listener.h"
14 #include <future>
15 #include <thread>
16 
17 using namespace lldb;
18 using namespace lldb_private;
19 
TEST(ListenerTest,GetEventImmediate)20 TEST(ListenerTest, GetEventImmediate) {
21   EventSP event_sp;
22   Broadcaster broadcaster(nullptr, "test-broadcaster");
23 
24   // Create a listener, sign it up, make sure it receives an event.
25   ListenerSP listener_sp = Listener::MakeListener("test-listener");
26   const uint32_t event_mask = 1;
27   ASSERT_EQ(event_mask,
28             listener_sp->StartListeningForEvents(&broadcaster, event_mask));
29 
30   const std::chrono::seconds timeout(0);
31   // Without any events sent, these should return false.
32   EXPECT_FALSE(listener_sp->GetEvent(event_sp, timeout));
33   EXPECT_FALSE(listener_sp->GetEventForBroadcaster(nullptr, event_sp, timeout));
34   EXPECT_FALSE(
35       listener_sp->GetEventForBroadcaster(&broadcaster, event_sp, timeout));
36   EXPECT_FALSE(listener_sp->GetEventForBroadcasterWithType(
37       &broadcaster, event_mask, event_sp, timeout));
38 
39   // Now send events and make sure they get it.
40   broadcaster.BroadcastEvent(event_mask, nullptr);
41   EXPECT_TRUE(listener_sp->GetEvent(event_sp, timeout));
42 
43   broadcaster.BroadcastEvent(event_mask, nullptr);
44   EXPECT_TRUE(listener_sp->GetEventForBroadcaster(nullptr, event_sp, timeout));
45 
46   broadcaster.BroadcastEvent(event_mask, nullptr);
47   EXPECT_TRUE(
48       listener_sp->GetEventForBroadcaster(&broadcaster, event_sp, timeout));
49 
50   broadcaster.BroadcastEvent(event_mask, nullptr);
51   EXPECT_FALSE(listener_sp->GetEventForBroadcasterWithType(
52       &broadcaster, event_mask * 2, event_sp, timeout));
53   EXPECT_TRUE(listener_sp->GetEventForBroadcasterWithType(
54       &broadcaster, event_mask, event_sp, timeout));
55 }
56 
TEST(ListenerTest,GetEventWait)57 TEST(ListenerTest, GetEventWait) {
58   EventSP event_sp;
59   Broadcaster broadcaster(nullptr, "test-broadcaster");
60 
61   // Create a listener, sign it up, make sure it receives an event.
62   ListenerSP listener_sp = Listener::MakeListener("test-listener");
63   const uint32_t event_mask = 1;
64   ASSERT_EQ(event_mask,
65             listener_sp->StartListeningForEvents(&broadcaster, event_mask));
66 
67   // Without any events sent, these should make a short wait and return false.
68   std::chrono::microseconds timeout(10);
69   EXPECT_FALSE(listener_sp->GetEvent(event_sp, timeout));
70   EXPECT_FALSE(listener_sp->GetEventForBroadcaster(nullptr, event_sp, timeout));
71   EXPECT_FALSE(
72       listener_sp->GetEventForBroadcaster(&broadcaster, event_sp, timeout));
73   EXPECT_FALSE(listener_sp->GetEventForBroadcasterWithType(
74       &broadcaster, event_mask, event_sp, timeout));
75 
76   // Now send events and make sure they get it.
77   broadcaster.BroadcastEvent(event_mask, nullptr);
78   EXPECT_TRUE(listener_sp->GetEvent(event_sp, timeout));
79 
80   broadcaster.BroadcastEvent(event_mask, nullptr);
81   EXPECT_TRUE(listener_sp->GetEventForBroadcaster(nullptr, event_sp, timeout));
82 
83   broadcaster.BroadcastEvent(event_mask, nullptr);
84   EXPECT_TRUE(
85       listener_sp->GetEventForBroadcaster(&broadcaster, event_sp, timeout));
86 
87   broadcaster.BroadcastEvent(event_mask, nullptr);
88   EXPECT_FALSE(listener_sp->GetEventForBroadcasterWithType(
89       &broadcaster, event_mask * 2, event_sp, timeout));
90   EXPECT_TRUE(listener_sp->GetEventForBroadcasterWithType(
91       &broadcaster, event_mask, event_sp, timeout));
92 
93   auto delayed_broadcast = [&] {
94     std::this_thread::sleep_for(std::chrono::milliseconds(10));
95     broadcaster.BroadcastEvent(event_mask, nullptr);
96   };
97 
98   // These should do an infinite wait at return the event our asynchronous
99   // broadcast sends.
100   std::future<void> async_broadcast =
101       std::async(std::launch::async, delayed_broadcast);
102   EXPECT_TRUE(listener_sp->GetEvent(event_sp, std::nullopt));
103   async_broadcast.get();
104 
105   async_broadcast = std::async(std::launch::async, delayed_broadcast);
106   EXPECT_TRUE(listener_sp->GetEventForBroadcaster(&broadcaster, event_sp,
107                                                   std::nullopt));
108   async_broadcast.get();
109 
110   async_broadcast = std::async(std::launch::async, delayed_broadcast);
111   EXPECT_TRUE(listener_sp->GetEventForBroadcasterWithType(
112       &broadcaster, event_mask, event_sp, std::nullopt));
113   async_broadcast.get();
114 }
115 
TEST(ListenerTest,StartStopListeningForEventSpec)116 TEST(ListenerTest, StartStopListeningForEventSpec) {
117   constexpr uint32_t event_mask = 1;
118   static constexpr llvm::StringLiteral broadcaster_class = "broadcaster-class";
119 
120   class TestBroadcaster : public Broadcaster {
121     using Broadcaster::Broadcaster;
122     llvm::StringRef GetBroadcasterClass() const override {
123       return broadcaster_class;
124     }
125   };
126 
127   BroadcasterManagerSP manager_sp =
128       BroadcasterManager::MakeBroadcasterManager();
129   ListenerSP listener_sp = Listener::MakeListener("test-listener");
130 
131   // Create two broadcasters, one while we're waiting for new broadcasters, and
132   // one when we're not.
133   ASSERT_EQ(listener_sp->StartListeningForEventSpec(
134                 manager_sp, BroadcastEventSpec(broadcaster_class, event_mask)),
135             event_mask);
136   TestBroadcaster broadcaster1(manager_sp, "test-broadcaster-1");
137   broadcaster1.CheckInWithManager();
138   ASSERT_TRUE(listener_sp->StopListeningForEventSpec(
139       manager_sp, BroadcastEventSpec(broadcaster_class, event_mask)));
140   TestBroadcaster broadcaster2(manager_sp, "test-broadcaster-2");
141   broadcaster2.CheckInWithManager();
142 
143   // Use both broadcasters to send an event.
144   for (auto *b : {&broadcaster1, &broadcaster2})
145     b->BroadcastEvent(event_mask, nullptr);
146 
147   // Use should only get the event from the first one.
148   EventSP event_sp;
149   ASSERT_TRUE(listener_sp->GetEvent(event_sp, std::chrono::seconds(0)));
150   ASSERT_EQ(event_sp->GetBroadcaster(), &broadcaster1);
151   ASSERT_FALSE(listener_sp->GetEvent(event_sp, std::chrono::seconds(0)));
152 }
153