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 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 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 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 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 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 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 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 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 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 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 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