|
11 | 11 | #include "lldb/Host/FileSystem.h"
|
12 | 12 | #include "lldb/Host/HostInfo.h"
|
13 | 13 | #include "gtest/gtest.h"
|
14 |
| - |
| 14 | +#include <fcntl.h> |
15 | 15 | #include <numeric>
|
16 | 16 | #include <vector>
|
17 | 17 |
|
@@ -58,58 +58,69 @@ TEST_F(PipeTest, OpenAsReader) {
|
58 | 58 | TEST_F(PipeTest, WriteWithTimeout) {
|
59 | 59 | Pipe pipe;
|
60 | 60 | ASSERT_THAT_ERROR(pipe.CreateNew(false).ToError(), llvm::Succeeded());
|
61 |
| - // Note write_chunk_size must be less than the pipe buffer. |
| 61 | + |
62 | 62 | // The pipe buffer is 1024 for PipeWindows and at least 512 on Darwin.
|
63 |
| - const size_t buf_size = 8192; |
| 63 | + // In Linux versions before 2.6.11, the capacity of a pipe was the same as the |
| 64 | + // system page size (e.g., 4096 bytes on i386). |
| 65 | + // Since Linux 2.6.11, the pipe capacity is 16 pages (i.e., 65,536 bytes in a |
| 66 | + // system with a page size of 4096 bytes). |
| 67 | + // Since Linux 2.6.35, the default pipe capacity is 16 pages, but the capacity |
| 68 | + // can be queried and set using the fcntl(2) F_GETPIPE_SZ and F_SETPIPE_SZ |
| 69 | + // operations: |
| 70 | + |
| 71 | +#if !defined(_WIN32) && defined(F_SETPIPE_SZ) |
| 72 | + ::fcntl(pipe.GetWriteFileDescriptor(), F_SETPIPE_SZ, 4096); |
| 73 | +#endif |
| 74 | + |
| 75 | + const size_t buf_size = 66000; |
| 76 | + |
| 77 | + // Note write_chunk_size must be less than the pipe buffer. |
64 | 78 | const size_t write_chunk_size = 234;
|
65 | 79 |
|
66 | 80 | std::vector<int32_t> write_buf(buf_size / sizeof(int32_t));
|
67 | 81 | std::iota(write_buf.begin(), write_buf.end(), 0);
|
68 | 82 | std::vector<int32_t> read_buf(write_buf.size() + 100, -1);
|
69 | 83 |
|
70 |
| - char *write_ptr = (char *)&write_buf.front(); |
71 |
| - char *read_ptr = (char *)&read_buf.front(); |
| 84 | + char *write_ptr = reinterpret_cast<char *>(write_buf.data()); |
| 85 | + char *read_ptr = reinterpret_cast<char *>(read_buf.data()); |
72 | 86 | size_t write_bytes = 0;
|
73 | 87 | size_t read_bytes = 0;
|
74 | 88 | size_t num_bytes = 0;
|
75 | 89 |
|
76 | 90 | // Write to the pipe until it is full.
|
77 |
| - while (write_bytes < buf_size) { |
| 91 | + while (write_bytes + write_chunk_size <= buf_size) { |
78 | 92 | Status error =
|
79 | 93 | pipe.WriteWithTimeout(write_ptr + write_bytes, write_chunk_size,
|
80 | 94 | std::chrono::milliseconds(10), num_bytes);
|
81 | 95 | if (error.Fail())
|
82 |
| - break; // The write buffer is full |
| 96 | + break; // The write buffer is full. |
83 | 97 | write_bytes += num_bytes;
|
84 | 98 | }
|
85 |
| - ASSERT_TRUE(write_bytes + write_chunk_size <= buf_size); |
| 99 | + ASSERT_LE(write_bytes + write_chunk_size, buf_size) |
| 100 | + << "Pipe buffer larger than expected"; |
86 | 101 |
|
87 | 102 | // Attempt a write with a long timeout.
|
88 | 103 | auto start_time = std::chrono::steady_clock::now();
|
89 |
| - ASSERT_THAT_ERROR( |
90 |
| - pipe.WriteWithTimeout(write_ptr + write_bytes, write_chunk_size, |
91 |
| - std::chrono::milliseconds(2000), num_bytes) |
92 |
| - .ToError(), |
93 |
| - llvm::Failed()); |
94 |
| - auto dur = std::chrono::duration_cast<std::chrono::milliseconds>( |
95 |
| - std::chrono::steady_clock::now() - start_time) |
96 |
| - .count(); |
97 |
| - ASSERT_GE(dur, 2000); |
| 104 | + ASSERT_THAT_ERROR(pipe.WriteWithTimeout(write_ptr + write_bytes, |
| 105 | + write_chunk_size, |
| 106 | + std::chrono::seconds(2), num_bytes) |
| 107 | + .ToError(), |
| 108 | + llvm::Failed()); |
| 109 | + auto dur = std::chrono::steady_clock::now() - start_time; |
| 110 | + ASSERT_GE(dur, std::chrono::seconds(2)); |
98 | 111 |
|
99 |
| - // Attempt a write with a short timeout |
| 112 | + // Attempt a write with a short timeout. |
100 | 113 | start_time = std::chrono::steady_clock::now();
|
101 | 114 | ASSERT_THAT_ERROR(
|
102 | 115 | pipe.WriteWithTimeout(write_ptr + write_bytes, write_chunk_size,
|
103 | 116 | std::chrono::milliseconds(200), num_bytes)
|
104 | 117 | .ToError(),
|
105 | 118 | llvm::Failed());
|
106 |
| - dur = std::chrono::duration_cast<std::chrono::milliseconds>( |
107 |
| - std::chrono::steady_clock::now() - start_time) |
108 |
| - .count(); |
109 |
| - ASSERT_GE(dur, 200); |
110 |
| - ASSERT_LT(dur, 300); |
| 119 | + dur = std::chrono::steady_clock::now() - start_time; |
| 120 | + ASSERT_GE(dur, std::chrono::milliseconds(200)); |
| 121 | + ASSERT_LT(dur, std::chrono::seconds(2)); |
111 | 122 |
|
112 |
| - // Drain the pipe |
| 123 | + // Drain the pipe. |
113 | 124 | while (read_bytes < write_bytes) {
|
114 | 125 | ASSERT_THAT_ERROR(
|
115 | 126 | pipe.ReadWithTimeout(read_ptr + read_bytes, write_bytes - read_bytes,
|
|
0 commit comments