diff options
author | Colin Cross <ccross@android.com> | 2023-05-13 02:32:11 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-05-13 02:32:11 +0000 |
commit | 600d84790777d7c435ba75c94839bd727c0cb19a (patch) | |
tree | 81425cadebc6a46958e6fd4ef0e4e83b5097a8d7 | |
parent | 7ff8b4477ac153240e471a56f9798eb29c53113b (diff) | |
parent | f5c02e0dd38c62f624d41606b0327e838ab72085 (diff) | |
download | adb-600d84790777d7c435ba75c94839bd727c0cb19a.tar.gz |
Add test showing calling unregistered event am: f5c02e0dd3
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/modules/adb/+/23122420
Change-Id: I751ae0d179e61fa9ac18dac6200777ee7b3bd83a
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | fdevent/fdevent_test.cpp | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/fdevent/fdevent_test.cpp b/fdevent/fdevent_test.cpp index 20a82ea4..4c334061 100644 --- a/fdevent/fdevent_test.cpp +++ b/fdevent/fdevent_test.cpp @@ -315,3 +315,86 @@ TEST_F(FdeventTest, timeout) { ASSERT_LT(diff[1], delta.count() * 0.5); ASSERT_LT(diff[2], delta.count() * 0.5); } + +TEST_F(FdeventTest, unregister_with_pending_event) { + fdevent_reset(); + + int fds1[2]; + int fds2[2]; + ASSERT_EQ(0, adb_socketpair(fds1)); + ASSERT_EQ(0, adb_socketpair(fds2)); + + struct Test { + fdevent* fde1; + fdevent* fde2; + bool should_not_happen; + }; + Test test{}; + + test.fde1 = fdevent_create( + fds1[0], + [](fdevent* fde, unsigned events, void* arg) { + auto test = static_cast<Test*>(arg); + // Unregister fde2 from inside the fde1 event + fdevent_destroy(test->fde2); + // Unregister fde1 so it doesn't get called again + fdevent_destroy(test->fde1); + }, + &test); + + test.fde2 = fdevent_create( + fds2[0], + [](fdevent* fde, unsigned events, void* arg) { + auto test = static_cast<Test*>(arg); + test->should_not_happen = true; + }, + &test); + + fdevent_add(test.fde1, FDE_READ | FDE_ERROR); + fdevent_add(test.fde2, FDE_READ | FDE_ERROR); + + PrepareThread(); + WaitForFdeventLoop(); + + std::mutex m; + std::condition_variable cv; + bool main_thread_latch = false; + bool looper_thread_latch = false; + + fdevent_run_on_looper([&]() { + std::unique_lock lk(m); + // Notify the main thread that the looper is in this lambda + main_thread_latch = true; + cv.notify_one(); + // Pause the looper to ensure both events occur in the same epoll_wait + cv.wait(lk, [&] { return looper_thread_latch; }); + }); + + // Wait for the looper thread to pause to ensure it is not in epoll_wait + { + std::unique_lock lk(m); + cv.wait(lk, [&] { return main_thread_latch; }); + } + + // Write to one end of the sockets to trigger events on the other ends + adb_write(fds1[1], "a", 1); + adb_write(fds2[1], "a", 1); + + // Unpause the looper thread to let it loop back into epoll_wait, which should return + // both fde1 and fde2. + { + std::lock_guard lk(m); + looper_thread_latch = true; + } + cv.notify_one(); + + WaitForFdeventLoop(); + TerminateThread(); + + adb_close(fds1[0]); + adb_close(fds1[1]); + adb_close(fds2[0]); + adb_close(fds2[1]); + + ASSERT_FALSE(test.should_not_happen); +} |