@@ -65,16 +65,20 @@ PipePosix::PipePosix(PipePosix &&pipe_posix)
65
65
pipe_posix.ReleaseWriteFileDescriptor ()} {}
66
66
67
67
PipePosix &PipePosix::operator =(PipePosix &&pipe_posix) {
68
+ std::scoped_lock guard (m_read_mutex, m_write_mutex, pipe_posix.m_read_mutex ,
69
+ pipe_posix.m_write_mutex );
70
+
68
71
PipeBase::operator =(std::move (pipe_posix));
69
- m_fds[READ] = pipe_posix.ReleaseReadFileDescriptor ();
70
- m_fds[WRITE] = pipe_posix.ReleaseWriteFileDescriptor ();
72
+ m_fds[READ] = pipe_posix.ReleaseReadFileDescriptorUnlocked ();
73
+ m_fds[WRITE] = pipe_posix.ReleaseWriteFileDescriptorUnlocked ();
71
74
return *this ;
72
75
}
73
76
74
77
PipePosix::~PipePosix () { Close (); }
75
78
76
79
Status PipePosix::CreateNew (bool child_processes_inherit) {
77
- if (CanRead () || CanWrite ())
80
+ std::scoped_lock guard (m_read_mutex, m_write_mutex);
81
+ if (CanReadUnlocked () || CanWriteUnlocked ())
78
82
return Status (EINVAL, eErrorTypePOSIX);
79
83
80
84
Status error;
@@ -87,7 +91,7 @@ Status PipePosix::CreateNew(bool child_processes_inherit) {
87
91
if (!child_processes_inherit) {
88
92
if (!SetCloexecFlag (m_fds[0 ]) || !SetCloexecFlag (m_fds[1 ])) {
89
93
error.SetErrorToErrno ();
90
- Close ();
94
+ CloseUnlocked ();
91
95
return error;
92
96
}
93
97
}
@@ -103,7 +107,8 @@ Status PipePosix::CreateNew(bool child_processes_inherit) {
103
107
}
104
108
105
109
Status PipePosix::CreateNew (llvm::StringRef name, bool child_process_inherit) {
106
- if (CanRead () || CanWrite ())
110
+ std::scoped_lock (m_read_mutex, m_write_mutex);
111
+ if (CanReadUnlocked () || CanWriteUnlocked ())
107
112
return Status (" Pipe is already opened" );
108
113
109
114
Status error;
@@ -140,7 +145,9 @@ Status PipePosix::CreateWithUniqueName(llvm::StringRef prefix,
140
145
141
146
Status PipePosix::OpenAsReader (llvm::StringRef name,
142
147
bool child_process_inherit) {
143
- if (CanRead () || CanWrite ())
148
+ std::scoped_lock (m_read_mutex, m_write_mutex);
149
+
150
+ if (CanReadUnlocked () || CanWriteUnlocked ())
144
151
return Status (" Pipe is already opened" );
145
152
146
153
int flags = O_RDONLY | O_NONBLOCK;
@@ -161,7 +168,8 @@ Status
161
168
PipePosix::OpenAsWriterWithTimeout (llvm::StringRef name,
162
169
bool child_process_inherit,
163
170
const std::chrono::microseconds &timeout) {
164
- if (CanRead () || CanWrite ())
171
+ std::lock_guard guard (m_write_mutex);
172
+ if (CanReadUnlocked () || CanWriteUnlocked ())
165
173
return Status (" Pipe is already opened" );
166
174
167
175
int flags = O_WRONLY | O_NONBLOCK;
@@ -171,7 +179,7 @@ PipePosix::OpenAsWriterWithTimeout(llvm::StringRef name,
171
179
using namespace std ::chrono;
172
180
const auto finish_time = Now () + timeout;
173
181
174
- while (!CanWrite ()) {
182
+ while (!CanWriteUnlocked ()) {
175
183
if (timeout != microseconds::zero ()) {
176
184
const auto dur = duration_cast<microseconds>(finish_time - Now ()).count ();
177
185
if (dur <= 0 )
@@ -196,48 +204,96 @@ PipePosix::OpenAsWriterWithTimeout(llvm::StringRef name,
196
204
return Status ();
197
205
}
198
206
199
- int PipePosix::GetReadFileDescriptor () const { return m_fds[READ]; }
207
+ int PipePosix::GetReadFileDescriptor () const {
208
+ std::lock_guard guard (m_read_mutex);
209
+ return GetReadFileDescriptorUnlocked ();
210
+ }
211
+
212
+ int PipePosix::GetReadFileDescriptorUnlocked () const {
213
+ return m_fds[READ];
214
+ }
200
215
201
- int PipePosix::GetWriteFileDescriptor () const { return m_fds[WRITE]; }
216
+ int PipePosix::GetWriteFileDescriptor () const {
217
+ std::lock_guard guard (m_write_mutex);
218
+ return GetWriteFileDescriptorUnlocked ();
219
+ }
220
+
221
+ int PipePosix::GetWriteFileDescriptorUnlocked () const {
222
+ return m_fds[WRITE];
223
+ }
202
224
203
225
int PipePosix::ReleaseReadFileDescriptor () {
226
+ std::lock_guard guard (m_read_mutex);
227
+ return ReleaseReadFileDescriptorUnlocked ();
228
+ }
229
+
230
+ int PipePosix::ReleaseReadFileDescriptorUnlocked () {
204
231
const int fd = m_fds[READ];
205
232
m_fds[READ] = PipePosix::kInvalidDescriptor ;
206
233
return fd;
207
234
}
208
235
209
236
int PipePosix::ReleaseWriteFileDescriptor () {
237
+ std::lock_guard guard (m_write_mutex);
238
+ return ReleaseWriteFileDescriptorUnlocked ();
239
+ }
240
+
241
+ int PipePosix::ReleaseWriteFileDescriptorUnlocked () {
210
242
const int fd = m_fds[WRITE];
211
243
m_fds[WRITE] = PipePosix::kInvalidDescriptor ;
212
244
return fd;
213
245
}
214
246
215
247
void PipePosix::Close () {
216
- CloseReadFileDescriptor ();
217
- CloseWriteFileDescriptor ();
248
+ std::scoped_lock guard (m_read_mutex, m_write_mutex);
249
+ CloseUnlocked ();
250
+ }
251
+
252
+ void PipePosix::CloseUnlocked () {
253
+ CloseReadFileDescriptorUnlocked ();
254
+ CloseWriteFileDescriptorUnlocked ();
218
255
}
219
256
220
257
Status PipePosix::Delete (llvm::StringRef name) {
221
258
return llvm::sys::fs::remove (name);
222
259
}
223
260
224
261
bool PipePosix::CanRead () const {
262
+ std::lock_guard guard (m_read_mutex);
263
+ return CanReadUnlocked ();
264
+ }
265
+
266
+ bool PipePosix::CanReadUnlocked () const {
225
267
return m_fds[READ] != PipePosix::kInvalidDescriptor ;
226
268
}
227
269
228
270
bool PipePosix::CanWrite () const {
271
+ std::lock_guard guard (m_write_mutex);
272
+ return CanWriteUnlocked ();
273
+ }
274
+
275
+ bool PipePosix::CanWriteUnlocked () const {
229
276
return m_fds[WRITE] != PipePosix::kInvalidDescriptor ;
230
277
}
231
278
232
279
void PipePosix::CloseReadFileDescriptor () {
233
- if (CanRead ()) {
280
+ std::lock_guard guard (m_read_mutex);
281
+ CloseReadFileDescriptorUnlocked ();
282
+ }
283
+ void PipePosix::CloseReadFileDescriptorUnlocked () {
284
+ if (CanReadUnlocked ()) {
234
285
close (m_fds[READ]);
235
286
m_fds[READ] = PipePosix::kInvalidDescriptor ;
236
287
}
237
288
}
238
289
239
290
void PipePosix::CloseWriteFileDescriptor () {
240
- if (CanWrite ()) {
291
+ std::lock_guard guard (m_write_mutex);
292
+ CloseWriteFileDescriptorUnlocked ();
293
+ }
294
+
295
+ void PipePosix::CloseWriteFileDescriptorUnlocked () {
296
+ if (CanWriteUnlocked ()) {
241
297
close (m_fds[WRITE]);
242
298
m_fds[WRITE] = PipePosix::kInvalidDescriptor ;
243
299
}
@@ -246,11 +302,12 @@ void PipePosix::CloseWriteFileDescriptor() {
246
302
Status PipePosix::ReadWithTimeout (void *buf, size_t size,
247
303
const std::chrono::microseconds &timeout,
248
304
size_t &bytes_read) {
305
+ std::lock_guard guard (m_read_mutex);
249
306
bytes_read = 0 ;
250
- if (!CanRead ())
307
+ if (!CanReadUnlocked ())
251
308
return Status (EINVAL, eErrorTypePOSIX);
252
309
253
- const int fd = GetReadFileDescriptor ();
310
+ const int fd = GetReadFileDescriptorUnlocked ();
254
311
255
312
SelectHelper select_helper;
256
313
select_helper.SetTimeout (timeout);
@@ -278,11 +335,12 @@ Status PipePosix::ReadWithTimeout(void *buf, size_t size,
278
335
}
279
336
280
337
Status PipePosix::Write (const void *buf, size_t size, size_t &bytes_written) {
338
+ std::lock_guard guard (m_write_mutex);
281
339
bytes_written = 0 ;
282
- if (!CanWrite ())
340
+ if (!CanWriteUnlocked ())
283
341
return Status (EINVAL, eErrorTypePOSIX);
284
342
285
- const int fd = GetWriteFileDescriptor ();
343
+ const int fd = GetWriteFileDescriptorUnlocked ();
286
344
SelectHelper select_helper;
287
345
select_helper.SetTimeout (std::chrono::seconds (0 ));
288
346
select_helper.FDSetWrite (fd);
0 commit comments