JDevlieghere updated this revision to Diff 548056. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D157347/new/
https://reviews.llvm.org/D157347 Files: lldb/include/lldb/Host/File.h lldb/source/Host/common/File.cpp
Index: lldb/source/Host/common/File.cpp =================================================================== --- lldb/source/Host/common/File.cpp +++ lldb/source/Host/common/File.cpp @@ -78,21 +78,20 @@ } Expected<File::OpenOptions> File::GetOptionsFromMode(llvm::StringRef mode) { - OpenOptions opts = - llvm::StringSwitch<OpenOptions>(mode) - .Cases("r", "rb", eOpenOptionReadOnly) - .Cases("w", "wb", eOpenOptionWriteOnly) - .Cases("a", "ab", - eOpenOptionWriteOnly | eOpenOptionAppend | - eOpenOptionCanCreate) - .Cases("r+", "rb+", "r+b", eOpenOptionReadWrite) - .Cases("w+", "wb+", "w+b", - eOpenOptionReadWrite | eOpenOptionCanCreate | - eOpenOptionTruncate) - .Cases("a+", "ab+", "a+b", - eOpenOptionReadWrite | eOpenOptionAppend | - eOpenOptionCanCreate) - .Default(eOpenOptionInvalid); + OpenOptions opts = llvm::StringSwitch<OpenOptions>(mode) + .Cases("r", "rb", eOpenOptionReadOnly) + .Cases("w", "wb", eOpenOptionWriteOnly) + .Cases("a", "ab", + eOpenOptionWriteOnly | eOpenOptionAppend | + eOpenOptionCanCreate) + .Cases("r+", "rb+", "r+b", eOpenOptionReadWrite) + .Cases("w+", "wb+", "w+b", + eOpenOptionReadWrite | eOpenOptionCanCreate | + eOpenOptionTruncate) + .Cases("a+", "ab+", "a+b", + eOpenOptionReadWrite | eOpenOptionAppend | + eOpenOptionCanCreate) + .Default(eOpenOptionInvalid); if (opts != eOpenOptionInvalid) return opts; return llvm::createStringError( @@ -219,7 +218,8 @@ size_t File::PrintfVarArg(const char *format, va_list args) { llvm::SmallString<0> s; if (VASprintf(s, format, args)) { - size_t written = s.size();; + size_t written = s.size(); + ; Write(s.data(), written); return written; } @@ -247,15 +247,20 @@ return file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); } +bool NativeFile::IsValid() const { + return DescriptorIsValid() || StreamIsValid(); +} + Expected<File::OpenOptions> NativeFile::GetOptions() const { return m_options; } int NativeFile::GetDescriptor() const { - if (DescriptorIsValid()) + if (ValueGuard descriptor_guard = DescriptorIsValid()) { return m_descriptor; + } // Don't open the file descriptor if we don't need to, just get it from the // stream if we have one. - if (StreamIsValid()) { + if (ValueGuard stream_guard = StreamIsValid()) { #if defined(_WIN32) return _fileno(m_stream); #else @@ -272,8 +277,9 @@ } FILE *NativeFile::GetStream() { - if (!StreamIsValid()) { - if (DescriptorIsValid()) { + ValueGuard stream_guard = StreamIsValid(); + if (!stream_guard) { + if (ValueGuard descriptor_guard = DescriptorIsValid()) { auto mode = GetStreamOpenModeFromOptions(m_options); if (!mode) llvm::consumeError(mode.takeError()); @@ -307,30 +313,39 @@ Status NativeFile::Close() { Status error; - if (StreamIsValid()) { - if (m_own_stream) { - if (::fclose(m_stream) == EOF) - error.SetErrorToErrno(); - } else { - File::OpenOptions rw = - m_options & (File::eOpenOptionReadOnly | File::eOpenOptionWriteOnly | - File::eOpenOptionReadWrite); - if (rw == eOpenOptionWriteOnly || rw == eOpenOptionReadWrite) { - if (::fflush(m_stream) == EOF) + { + ValueGuard stream_guard = StreamIsValid(); + if (stream_guard) { + if (m_own_stream) { + if (::fclose(m_stream) == EOF) error.SetErrorToErrno(); + } else { + File::OpenOptions rw = m_options & (File::eOpenOptionReadOnly | + File::eOpenOptionWriteOnly | + File::eOpenOptionReadWrite); + + if (rw == eOpenOptionWriteOnly || rw == eOpenOptionReadWrite) { + if (::fflush(m_stream) == EOF) + error.SetErrorToErrno(); + } } } + m_stream = kInvalidStream; + m_own_stream = false; } - if (DescriptorIsValid() && m_own_descriptor) { - if (::close(m_descriptor) != 0) - error.SetErrorToErrno(); + + { + ValueGuard descriptor_guard = DescriptorIsValid(); + if (descriptor_guard && m_own_descriptor) { + if (::close(m_descriptor) != 0) + error.SetErrorToErrno(); + } + m_descriptor = kInvalidDescriptor; + m_own_descriptor = false; } - m_descriptor = kInvalidDescriptor; - m_stream = kInvalidStream; + m_options = OpenOptions(0); - m_own_stream = false; - m_own_descriptor = false; m_is_interactive = eLazyBoolCalculate; m_is_real_terminal = eLazyBoolCalculate; return error; @@ -374,7 +389,7 @@ off_t NativeFile::SeekFromStart(off_t offset, Status *error_ptr) { off_t result = 0; - if (DescriptorIsValid()) { + if (ValueGuard descriptor_guard = DescriptorIsValid()) { result = ::lseek(m_descriptor, offset, SEEK_SET); if (error_ptr) { @@ -383,7 +398,7 @@ else error_ptr->Clear(); } - } else if (StreamIsValid()) { + } else if (ValueGuard stream_guard = StreamIsValid()) { result = ::fseek(m_stream, offset, SEEK_SET); if (error_ptr) { @@ -400,7 +415,7 @@ off_t NativeFile::SeekFromCurrent(off_t offset, Status *error_ptr) { off_t result = -1; - if (DescriptorIsValid()) { + if (ValueGuard descriptor_guard = DescriptorIsValid()) { result = ::lseek(m_descriptor, offset, SEEK_CUR); if (error_ptr) { @@ -409,7 +424,7 @@ else error_ptr->Clear(); } - } else if (StreamIsValid()) { + } else if (ValueGuard stream_guard = StreamIsValid()) { result = ::fseek(m_stream, offset, SEEK_CUR); if (error_ptr) { @@ -426,7 +441,7 @@ off_t NativeFile::SeekFromEnd(off_t offset, Status *error_ptr) { off_t result = -1; - if (DescriptorIsValid()) { + if (ValueGuard descriptor_guard = DescriptorIsValid()) { result = ::lseek(m_descriptor, offset, SEEK_END); if (error_ptr) { @@ -435,7 +450,7 @@ else error_ptr->Clear(); } - } else if (StreamIsValid()) { + } else if (ValueGuard stream_guard = StreamIsValid()) { result = ::fseek(m_stream, offset, SEEK_END); if (error_ptr) { @@ -452,18 +467,23 @@ Status NativeFile::Flush() { Status error; - if (StreamIsValid()) { + if (ValueGuard stream_guard = StreamIsValid()) { if (llvm::sys::RetryAfterSignal(EOF, ::fflush, m_stream) == EOF) error.SetErrorToErrno(); - } else if (!DescriptorIsValid()) { - error.SetErrorString("invalid file handle"); + return error; + } + + { + ValueGuard descriptor_guard = DescriptorIsValid(); + if (!descriptor_guard) + error.SetErrorString("invalid file handle"); } return error; } Status NativeFile::Sync() { Status error; - if (DescriptorIsValid()) { + if (ValueGuard descriptor_guard = DescriptorIsValid()) { #ifdef _WIN32 int err = FlushFileBuffers((HANDLE)_get_osfhandle(m_descriptor)); if (err == 0) @@ -518,14 +538,15 @@ #endif ssize_t bytes_read = -1; - if (DescriptorIsValid()) { - bytes_read = llvm::sys::RetryAfterSignal(-1, ::read, m_descriptor, buf, num_bytes); + if (ValueGuard descriptor_guard = DescriptorIsValid()) { + bytes_read = + llvm::sys::RetryAfterSignal(-1, ::read, m_descriptor, buf, num_bytes); if (bytes_read == -1) { error.SetErrorToErrno(); num_bytes = 0; } else num_bytes = bytes_read; - } else if (StreamIsValid()) { + } else if (ValueGuard file_lock = StreamIsValid()) { bytes_read = ::fread(buf, 1, num_bytes, m_stream); if (bytes_read == 0) { @@ -577,7 +598,7 @@ #endif ssize_t bytes_written = -1; - if (DescriptorIsValid()) { + if (ValueGuard descriptor_guard = DescriptorIsValid()) { bytes_written = llvm::sys::RetryAfterSignal(-1, ::write, m_descriptor, buf, num_bytes); if (bytes_written == -1) { @@ -585,7 +606,7 @@ num_bytes = 0; } else num_bytes = bytes_written; - } else if (StreamIsValid()) { + } else if (ValueGuard stream_guard = StreamIsValid()) { bytes_written = ::fwrite(buf, 1, num_bytes, m_stream); if (bytes_written == 0) { @@ -596,7 +617,6 @@ num_bytes = 0; } else num_bytes = bytes_written; - } else { num_bytes = 0; error.SetErrorString("invalid file handle"); @@ -701,8 +721,8 @@ int fd = GetDescriptor(); if (fd != kInvalidDescriptor) { #ifndef _WIN32 - ssize_t bytes_written = - llvm::sys::RetryAfterSignal(-1, ::pwrite, m_descriptor, buf, num_bytes, offset); + ssize_t bytes_written = llvm::sys::RetryAfterSignal( + -1, ::pwrite, m_descriptor, buf, num_bytes, offset); if (bytes_written < 0) { num_bytes = 0; error.SetErrorToErrno(); Index: lldb/include/lldb/Host/File.h =================================================================== --- lldb/include/lldb/Host/File.h +++ lldb/include/lldb/Host/File.h @@ -389,9 +389,7 @@ ~NativeFile() override { Close(); } - bool IsValid() const override { - return DescriptorIsValid() || StreamIsValid(); - } + bool IsValid() const override; Status Read(void *buf, size_t &num_bytes) override; Status Write(const void *buf, size_t &num_bytes) override; @@ -417,15 +415,31 @@ static bool classof(const File *file) { return file->isA(&ID); } protected: - bool DescriptorIsValid() const { - return File::DescriptorIsValid(m_descriptor); + struct ValueGuard { + ValueGuard(std::mutex &m, bool b) : guard(m, std::adopt_lock), value(b) {} + std::lock_guard<std::mutex> guard; + bool value; + operator bool() { return value; } + }; + + ValueGuard DescriptorIsValid() const { + m_descriptor_mutex.lock(); + return ValueGuard(m_descriptor_mutex, + File::DescriptorIsValid(m_descriptor)); + } + + ValueGuard StreamIsValid() const { + m_stream_mutex.lock(); + return ValueGuard(m_stream_mutex, m_stream != kInvalidStream); } - bool StreamIsValid() const { return m_stream != kInvalidStream; } - // Member variables int m_descriptor; bool m_own_descriptor = false; + mutable std::mutex m_descriptor_mutex; + FILE *m_stream; + mutable std::mutex m_stream_mutex; + OpenOptions m_options{}; bool m_own_stream = false; std::mutex offset_access_mutex;
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits