1 /*
2  * Copyright 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "BufferHubEventFdTest"
18 
19 #include <sys/epoll.h>
20 #include <sys/eventfd.h>
21 
22 #include <array>
23 #include <condition_variable>
24 #include <mutex>
25 #include <thread>
26 
27 #include <gmock/gmock.h>
28 #include <gtest/gtest.h>
29 #include <log/log.h>
30 #include <ui/BufferHubEventFd.h>
31 
32 namespace android {
33 
34 namespace {
35 
36 const int kTimeout = 100;
37 const std::chrono::milliseconds kTimeoutMs(kTimeout);
38 const int kTestRuns = 5;
39 
40 using ::testing::Contains;
41 using BufferHubEventFdTest = ::testing::Test;
42 
43 } // namespace
44 
TEST_F(BufferHubEventFdTest,EventFd_testSingleEpollFd)45 TEST_F(BufferHubEventFdTest, EventFd_testSingleEpollFd) {
46     BufferHubEventFd eventFd;
47     ASSERT_TRUE(eventFd.isValid());
48 
49     base::unique_fd epollFd(epoll_create(64));
50     ASSERT_GE(epollFd.get(), 0);
51 
52     epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
53     ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
54 
55     std::array<epoll_event, 1> events;
56     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
57 
58     eventFd.signal();
59     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
60 
61     // The epoll fd is edge triggered, so it only responds to the eventFd once.
62     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
63 
64     // Check that it can receive consecutive signal.
65     eventFd.signal();
66     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
67     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
68 
69     // Check that it can receive consecutive signal from a duplicated eventfd.
70     BufferHubEventFd dupEventFd(dup(eventFd.get()));
71     ASSERT_TRUE(dupEventFd.isValid());
72     dupEventFd.signal();
73     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
74     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
75     dupEventFd.signal();
76     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
77     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
78 }
79 
TEST_F(BufferHubEventFdTest,EventFd_testCreateEpollFdAndAddSignaledEventFd)80 TEST_F(BufferHubEventFdTest, EventFd_testCreateEpollFdAndAddSignaledEventFd) {
81     BufferHubEventFd eventFd;
82     ASSERT_TRUE(eventFd.isValid());
83     eventFd.signal();
84 
85     base::unique_fd epollFd(epoll_create(64));
86     ASSERT_GE(epollFd.get(), 0);
87 
88     // Make sure that the epoll set has not been signal yet.
89     std::array<epoll_event, 1> events;
90     ASSERT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
91 
92     // Check that adding an signaled fd into this epoll set will trigger the epoll set.
93     epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
94     ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
95     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
96 
97     // The epoll fd is edge triggered, so it only responds to the eventFd once.
98     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
99 }
100 
TEST_F(BufferHubEventFdTest,EventFd_testAddSignaledEventFdToEpollFd)101 TEST_F(BufferHubEventFdTest, EventFd_testAddSignaledEventFdToEpollFd) {
102     BufferHubEventFd eventFd;
103     ASSERT_TRUE(eventFd.isValid());
104 
105     base::unique_fd epollFd(epoll_create(64));
106     ASSERT_GE(epollFd.get(), 0);
107 
108     eventFd.signal();
109 
110     epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
111     ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
112 
113     std::array<epoll_event, 1> events;
114     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
115 
116     // The epoll fd is edge triggered, so it only responds to the eventFd once.
117     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
118 }
119 
TEST_F(BufferHubEventFdTest,EventFd_testConsecutiveSignalsFromAEventFd)120 TEST_F(BufferHubEventFdTest, EventFd_testConsecutiveSignalsFromAEventFd) {
121     BufferHubEventFd eventFd;
122     ASSERT_TRUE(eventFd.isValid());
123     base::unique_fd epollFd(epoll_create(64));
124     ASSERT_GE(epollFd.get(), 0);
125     epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
126     ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
127 
128     std::array<epoll_event, 1> events;
129     for (int i = 0; i < kTestRuns; ++i) {
130         eventFd.signal();
131         EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
132         EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
133     }
134 }
135 
TEST_F(BufferHubEventFdTest,EventFd_testConsecutiveSignalsFromADuplicatedEventFd)136 TEST_F(BufferHubEventFdTest, EventFd_testConsecutiveSignalsFromADuplicatedEventFd) {
137     BufferHubEventFd eventFd;
138     ASSERT_TRUE(eventFd.isValid());
139     base::unique_fd epollFd(epoll_create(64));
140     ASSERT_GE(epollFd.get(), 0);
141     epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
142     ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
143 
144     BufferHubEventFd dupEventFd(dup(eventFd.get()));
145     ASSERT_TRUE(dupEventFd.isValid());
146 
147     std::array<epoll_event, 1> events;
148     for (int i = 0; i < kTestRuns; ++i) {
149         dupEventFd.signal();
150         EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
151         EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
152     }
153 }
154 
TEST_F(BufferHubEventFdTest,EventFd_testClear)155 TEST_F(BufferHubEventFdTest, EventFd_testClear) {
156     BufferHubEventFd eventFd;
157     ASSERT_TRUE(eventFd.isValid());
158 
159     base::unique_fd epollFd(epoll_create(64));
160     epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
161 
162     ASSERT_GE(epollFd.get(), 0);
163     ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
164 
165     eventFd.signal();
166     eventFd.clear();
167 
168     std::array<epoll_event, 1> events;
169     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
170 }
171 
TEST_F(BufferHubEventFdTest,EventFd_testDupEventFd)172 TEST_F(BufferHubEventFdTest, EventFd_testDupEventFd) {
173     BufferHubEventFd eventFd;
174     ASSERT_TRUE(eventFd.isValid());
175 
176     base::unique_fd epollFd(epoll_create(64));
177     epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
178 
179     ASSERT_GE(epollFd.get(), 0);
180     ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
181 
182     // Technically, the dupliated eventFd and the original eventFd are pointing
183     // to the same kernel object. This test signals the duplicated eventFd but epolls the origianl
184     // eventFd.
185     BufferHubEventFd dupedEventFd(dup(eventFd.get()));
186     ASSERT_GE(dupedEventFd.get(), 0);
187 
188     std::array<epoll_event, 1> events;
189     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
190 
191     dupedEventFd.signal();
192     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
193 
194     // The epoll fd is edge triggered, so it only responds to the eventFd once.
195     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
196 
197     dupedEventFd.signal();
198 
199     dupedEventFd.clear();
200     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
201 }
202 
TEST_F(BufferHubEventFdTest,EventFd_testTwoEpollFds)203 TEST_F(BufferHubEventFdTest, EventFd_testTwoEpollFds) {
204     BufferHubEventFd eventFd;
205     ASSERT_TRUE(eventFd.isValid());
206 
207     base::unique_fd epollFd1(epoll_create(64));
208     base::unique_fd epollFd2(epoll_create(64));
209     epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
210 
211     ASSERT_GE(epollFd1.get(), 0);
212     ASSERT_GE(epollFd2.get(), 0);
213 
214     // Register the same eventFd to two EpollFds.
215     ASSERT_EQ(epoll_ctl(epollFd1.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
216     ASSERT_EQ(epoll_ctl(epollFd2.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
217 
218     std::array<epoll_event, 1> events;
219     EXPECT_EQ(epoll_wait(epollFd1.get(), events.data(), events.size(), 0), 0);
220     EXPECT_EQ(epoll_wait(epollFd2.get(), events.data(), events.size(), 0), 0);
221 
222     eventFd.signal();
223     EXPECT_EQ(epoll_wait(epollFd1.get(), events.data(), events.size(), 0), 1);
224     EXPECT_EQ(epoll_wait(epollFd2.get(), events.data(), events.size(), 0), 1);
225 
226     // The epoll fd is edge triggered, so it only responds to the eventFd once.
227     EXPECT_EQ(epoll_wait(epollFd1.get(), events.data(), events.size(), 0), 0);
228     EXPECT_EQ(epoll_wait(epollFd2.get(), events.data(), events.size(), 0), 0);
229 
230     eventFd.signal();
231     EXPECT_EQ(epoll_wait(epollFd1.get(), events.data(), events.size(), 0), 1);
232 
233     eventFd.clear();
234     EXPECT_EQ(epoll_wait(epollFd1.get(), events.data(), events.size(), 0), 0);
235     EXPECT_EQ(epoll_wait(epollFd2.get(), events.data(), events.size(), 0), 0);
236 }
237 
TEST_F(BufferHubEventFdTest,EventFd_testTwoEventFds)238 TEST_F(BufferHubEventFdTest, EventFd_testTwoEventFds) {
239     BufferHubEventFd eventFd1;
240     BufferHubEventFd eventFd2;
241 
242     ASSERT_TRUE(eventFd1.isValid());
243     ASSERT_TRUE(eventFd2.isValid());
244 
245     base::unique_fd epollFd(epoll_create(64));
246     epoll_event e1 = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 1}};
247     epoll_event e2 = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 2}};
248 
249     ASSERT_GE(epollFd.get(), 0);
250     ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd1.get(), &e1), 0);
251     ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd2.get(), &e2), 0);
252 
253     std::array<epoll_event, 2> events;
254     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
255 
256     // Signal one by one.
257     eventFd1.signal();
258     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
259     EXPECT_EQ(events[0].data.u32, e1.data.u32);
260 
261     eventFd2.signal();
262     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
263     EXPECT_EQ(events[0].data.u32, e2.data.u32);
264 
265     // Signal both.
266     eventFd1.signal();
267     eventFd2.signal();
268     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 2);
269 
270     uint32_t u32s[] = {events[0].data.u32, events[1].data.u32};
271     EXPECT_THAT(u32s, Contains(e1.data.u32));
272     EXPECT_THAT(u32s, Contains(e2.data.u32));
273 
274     // The epoll fd is edge triggered, so it only responds to the eventFd once.
275     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 0);
276 
277     eventFd1.signal();
278     eventFd2.signal();
279     eventFd2.clear();
280     EXPECT_EQ(epoll_wait(epollFd.get(), events.data(), events.size(), 0), 1);
281 }
282 
TEST_F(BufferHubEventFdTest,EventFd_testPollingThreadWithTwoEventFds)283 TEST_F(BufferHubEventFdTest, EventFd_testPollingThreadWithTwoEventFds) {
284     BufferHubEventFd eventFd1;
285     BufferHubEventFd eventFd2;
286 
287     ASSERT_TRUE(eventFd1.isValid());
288     ASSERT_TRUE(eventFd2.isValid());
289 
290     base::unique_fd epollFd(epoll_create(64));
291     epoll_event e1 = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 1}};
292     epoll_event e2 = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 2}};
293 
294     ASSERT_GE(epollFd.get(), 0);
295     ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd1.get(), &e1), 0);
296     ASSERT_EQ(epoll_ctl(epollFd.get(), EPOLL_CTL_ADD, eventFd2.get(), &e2), 0);
297 
298     int countEvent1 = 0;
299     int countEvent2 = 0;
300     std::atomic<bool> stop{false};
301     std::mutex mx;
302     std::condition_variable cv;
303 
304     std::thread pollingThread([&] {
305         std::array<epoll_event, 2> events;
306         while (true) {
307             if (stop.load()) {
308                 break;
309             }
310             int ret = epoll_wait(epollFd.get(), events.data(), events.size(), kTimeout);
311             ALOGE_IF(ret < 0 && errno != ETIMEDOUT, "Epoll failed.");
312 
313             std::lock_guard<std::mutex> lock(mx);
314             for (int i = 0; i < ret; i++) {
315                 if (events[i].data.u32 == e1.data.u32) {
316                     countEvent1++;
317                     cv.notify_one();
318                 } else if (events[i].data.u32 == e2.data.u32) {
319                     countEvent2++;
320                     cv.notify_one();
321                 }
322             }
323         }
324     });
325 
326     {
327         std::unique_lock<std::mutex> lock(mx);
328 
329         eventFd1.signal();
330         EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEvent1 == 1; }));
331 
332         eventFd1.signal();
333         EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEvent1 == 2; }));
334 
335         eventFd2.signal();
336         EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEvent2 == 1; }));
337 
338         eventFd1.clear();
339         eventFd2.clear();
340         EXPECT_EQ(countEvent1, 2);
341         EXPECT_EQ(countEvent2, 1);
342 
343         eventFd1.signal();
344         EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEvent1 == 3; }));
345 
346         eventFd2.signal();
347         EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEvent2 == 2; }));
348     }
349 
350     stop.store(true);
351     pollingThread.join();
352 }
353 
TEST_F(BufferHubEventFdTest,EventFd_testTwoPollingThreads)354 TEST_F(BufferHubEventFdTest, EventFd_testTwoPollingThreads) {
355     BufferHubEventFd eventFd;
356     ASSERT_TRUE(eventFd.isValid());
357 
358     base::unique_fd epollFd1(epoll_create(64));
359     base::unique_fd epollFd2(epoll_create(64));
360     epoll_event e = {.events = EPOLLIN | EPOLLET, .data = {.u32 = 0}};
361 
362     ASSERT_GE(epollFd1.get(), 0);
363     ASSERT_GE(epollFd2.get(), 0);
364 
365     // Register the same eventFd to two EpollFds.
366     ASSERT_EQ(epoll_ctl(epollFd1.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
367     ASSERT_EQ(epoll_ctl(epollFd2.get(), EPOLL_CTL_ADD, eventFd.get(), &e), 0);
368 
369     int countEpoll1 = 0;
370     int countEpoll2 = 0;
371     std::atomic<bool> stop{false};
372     std::mutex mx;
373     std::condition_variable cv;
374 
375     std::thread pollingThread1([&] {
376         std::array<epoll_event, 1> events;
377         while (!stop.load()) {
378             int ret = epoll_wait(epollFd1.get(), events.data(), events.size(), kTimeout);
379             ALOGE_IF(ret < 0 && errno != ETIMEDOUT, "Epoll failed.");
380 
381             if (ret > 0) {
382                 std::lock_guard<std::mutex> lock(mx);
383                 countEpoll1++;
384                 cv.notify_one();
385             }
386         }
387     });
388 
389     std::thread pollingThread2([&] {
390         std::array<epoll_event, 1> events;
391         while (!stop.load()) {
392             int ret = epoll_wait(epollFd2.get(), events.data(), events.size(), kTimeout);
393             ALOGE_IF(ret < 0 && errno != ETIMEDOUT, "Epoll failed.");
394 
395             if (ret > 0) {
396                 std::lock_guard<std::mutex> lock(mx);
397                 countEpoll2++;
398                 cv.notify_one();
399             }
400         }
401     });
402 
403     {
404         std::unique_lock<std::mutex> lock(mx);
405 
406         eventFd.signal();
407         EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEpoll1 == 1; }));
408         EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEpoll2 == 1; }));
409 
410         eventFd.signal();
411         EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEpoll1 == 2; }));
412         EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEpoll2 == 2; }));
413 
414         eventFd.clear();
415         EXPECT_EQ(countEpoll1, 2);
416         EXPECT_EQ(countEpoll2, 2);
417 
418         eventFd.signal();
419         EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEpoll1 == 3; }));
420         EXPECT_TRUE(cv.wait_for(lock, kTimeoutMs, [&] { return countEpoll2 == 3; }));
421     }
422 
423     stop.store(true);
424     pollingThread1.join();
425     pollingThread2.join();
426 }
427 
428 } // namespace android
429