|
15 | 15 | #include "llvm/Testing/Support/Error.h"
|
16 | 16 | #include "gtest/gtest.h"
|
17 | 17 | #include <future>
|
| 18 | +#include <thread> |
18 | 19 |
|
19 | 20 | using namespace lldb_private;
|
20 | 21 |
|
@@ -78,6 +79,44 @@ TEST_F(MainLoopTest, ReadObject) {
|
78 | 79 | ASSERT_EQ(1u, callback_count);
|
79 | 80 | }
|
80 | 81 |
|
| 82 | +TEST_F(MainLoopTest, NoSpuriousReads) { |
| 83 | + // Write one byte into the socket. |
| 84 | + char X = 'X'; |
| 85 | + size_t len = sizeof(X); |
| 86 | + ASSERT_TRUE(socketpair[0]->Write(&X, len).Success()); |
| 87 | + |
| 88 | + MainLoop loop; |
| 89 | + |
| 90 | + Status error; |
| 91 | + auto handle = loop.RegisterReadObject( |
| 92 | + socketpair[1], |
| 93 | + [this](MainLoopBase &) { |
| 94 | + if (callback_count == 0) { |
| 95 | + // Read the byte back the first time we're called. After that, the |
| 96 | + // socket is empty, and we should not be called anymore. |
| 97 | + char X; |
| 98 | + size_t len = sizeof(X); |
| 99 | + EXPECT_THAT_ERROR(socketpair[1]->Read(&X, len).ToError(), |
| 100 | + llvm::Succeeded()); |
| 101 | + EXPECT_EQ(len, sizeof(X)); |
| 102 | + } |
| 103 | + ++callback_count; |
| 104 | + }, |
| 105 | + error); |
| 106 | + ASSERT_THAT_ERROR(error.ToError(), llvm::Succeeded()); |
| 107 | + // Terminate the loop after one second. |
| 108 | + std::thread terminate_thread([&loop] { |
| 109 | + std::this_thread::sleep_for(std::chrono::seconds(1)); |
| 110 | + loop.AddPendingCallback( |
| 111 | + [](MainLoopBase &loop) { loop.RequestTermination(); }); |
| 112 | + }); |
| 113 | + ASSERT_THAT_ERROR(loop.Run().ToError(), llvm::Succeeded()); |
| 114 | + terminate_thread.join(); |
| 115 | + |
| 116 | + // Make sure the callback was called only once. |
| 117 | + ASSERT_EQ(1u, callback_count); |
| 118 | +} |
| 119 | + |
81 | 120 | TEST_F(MainLoopTest, TerminatesImmediately) {
|
82 | 121 | char X = 'X';
|
83 | 122 | size_t len = sizeof(X);
|
|
0 commit comments