@@ -65,16 +65,20 @@ PipePosix::PipePosix(PipePosix &&pipe_posix)
6565 pipe_posix.ReleaseWriteFileDescriptor ()} {}
6666
6767PipePosix &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+
6871 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 ();
7174 return *this ;
7275}
7376
7477PipePosix::~PipePosix () { Close (); }
7578
7679Status 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 ())
7882 return Status (EINVAL, eErrorTypePOSIX);
7983
8084 Status error;
@@ -87,7 +91,7 @@ Status PipePosix::CreateNew(bool child_processes_inherit) {
8791 if (!child_processes_inherit) {
8892 if (!SetCloexecFlag (m_fds[0 ]) || !SetCloexecFlag (m_fds[1 ])) {
8993 error.SetErrorToErrno ();
90- Close ();
94+ CloseUnlocked ();
9195 return error;
9296 }
9397 }
@@ -103,7 +107,8 @@ Status PipePosix::CreateNew(bool child_processes_inherit) {
103107}
104108
105109Status 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 ())
107112 return Status (" Pipe is already opened" );
108113
109114 Status error;
@@ -140,7 +145,9 @@ Status PipePosix::CreateWithUniqueName(llvm::StringRef prefix,
140145
141146Status PipePosix::OpenAsReader (llvm::StringRef name,
142147 bool child_process_inherit) {
143- if (CanRead () || CanWrite ())
148+ std::scoped_lock (m_read_mutex, m_write_mutex);
149+
150+ if (CanReadUnlocked () || CanWriteUnlocked ())
144151 return Status (" Pipe is already opened" );
145152
146153 int flags = O_RDONLY | O_NONBLOCK;
@@ -161,7 +168,8 @@ Status
161168PipePosix::OpenAsWriterWithTimeout (llvm::StringRef name,
162169 bool child_process_inherit,
163170 const std::chrono::microseconds &timeout) {
164- if (CanRead () || CanWrite ())
171+ std::lock_guard guard (m_write_mutex);
172+ if (CanReadUnlocked () || CanWriteUnlocked ())
165173 return Status (" Pipe is already opened" );
166174
167175 int flags = O_WRONLY | O_NONBLOCK;
@@ -171,7 +179,7 @@ PipePosix::OpenAsWriterWithTimeout(llvm::StringRef name,
171179 using namespace std ::chrono;
172180 const auto finish_time = Now () + timeout;
173181
174- while (!CanWrite ()) {
182+ while (!CanWriteUnlocked ()) {
175183 if (timeout != microseconds::zero ()) {
176184 const auto dur = duration_cast<microseconds>(finish_time - Now ()).count ();
177185 if (dur <= 0 )
@@ -196,48 +204,96 @@ PipePosix::OpenAsWriterWithTimeout(llvm::StringRef name,
196204 return Status ();
197205}
198206
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+ }
200215
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+ }
202224
203225int PipePosix::ReleaseReadFileDescriptor () {
226+ std::lock_guard guard (m_read_mutex);
227+ return ReleaseReadFileDescriptorUnlocked ();
228+ }
229+
230+ int PipePosix::ReleaseReadFileDescriptorUnlocked () {
204231 const int fd = m_fds[READ];
205232 m_fds[READ] = PipePosix::kInvalidDescriptor ;
206233 return fd;
207234}
208235
209236int PipePosix::ReleaseWriteFileDescriptor () {
237+ std::lock_guard guard (m_write_mutex);
238+ return ReleaseWriteFileDescriptorUnlocked ();
239+ }
240+
241+ int PipePosix::ReleaseWriteFileDescriptorUnlocked () {
210242 const int fd = m_fds[WRITE];
211243 m_fds[WRITE] = PipePosix::kInvalidDescriptor ;
212244 return fd;
213245}
214246
215247void 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 ();
218255}
219256
220257Status PipePosix::Delete (llvm::StringRef name) {
221258 return llvm::sys::fs::remove (name);
222259}
223260
224261bool PipePosix::CanRead () const {
262+ std::lock_guard guard (m_read_mutex);
263+ return CanReadUnlocked ();
264+ }
265+
266+ bool PipePosix::CanReadUnlocked () const {
225267 return m_fds[READ] != PipePosix::kInvalidDescriptor ;
226268}
227269
228270bool PipePosix::CanWrite () const {
271+ std::lock_guard guard (m_write_mutex);
272+ return CanWriteUnlocked ();
273+ }
274+
275+ bool PipePosix::CanWriteUnlocked () const {
229276 return m_fds[WRITE] != PipePosix::kInvalidDescriptor ;
230277}
231278
232279void PipePosix::CloseReadFileDescriptor () {
233- if (CanRead ()) {
280+ std::lock_guard guard (m_read_mutex);
281+ CloseReadFileDescriptorUnlocked ();
282+ }
283+ void PipePosix::CloseReadFileDescriptorUnlocked () {
284+ if (CanReadUnlocked ()) {
234285 close (m_fds[READ]);
235286 m_fds[READ] = PipePosix::kInvalidDescriptor ;
236287 }
237288}
238289
239290void PipePosix::CloseWriteFileDescriptor () {
240- if (CanWrite ()) {
291+ std::lock_guard guard (m_write_mutex);
292+ CloseWriteFileDescriptorUnlocked ();
293+ }
294+
295+ void PipePosix::CloseWriteFileDescriptorUnlocked () {
296+ if (CanWriteUnlocked ()) {
241297 close (m_fds[WRITE]);
242298 m_fds[WRITE] = PipePosix::kInvalidDescriptor ;
243299 }
@@ -246,11 +302,12 @@ void PipePosix::CloseWriteFileDescriptor() {
246302Status PipePosix::ReadWithTimeout (void *buf, size_t size,
247303 const std::chrono::microseconds &timeout,
248304 size_t &bytes_read) {
305+ std::lock_guard guard (m_read_mutex);
249306 bytes_read = 0 ;
250- if (!CanRead ())
307+ if (!CanReadUnlocked ())
251308 return Status (EINVAL, eErrorTypePOSIX);
252309
253- const int fd = GetReadFileDescriptor ();
310+ const int fd = GetReadFileDescriptorUnlocked ();
254311
255312 SelectHelper select_helper;
256313 select_helper.SetTimeout (timeout);
@@ -278,11 +335,12 @@ Status PipePosix::ReadWithTimeout(void *buf, size_t size,
278335}
279336
280337Status PipePosix::Write (const void *buf, size_t size, size_t &bytes_written) {
338+ std::lock_guard guard (m_write_mutex);
281339 bytes_written = 0 ;
282- if (!CanWrite ())
340+ if (!CanWriteUnlocked ())
283341 return Status (EINVAL, eErrorTypePOSIX);
284342
285- const int fd = GetWriteFileDescriptor ();
343+ const int fd = GetWriteFileDescriptorUnlocked ();
286344 SelectHelper select_helper;
287345 select_helper.SetTimeout (std::chrono::seconds (0 ));
288346 select_helper.FDSetWrite (fd);
0 commit comments