diff options
author | Peter Klausler <pklausler@nvidia.com> | 2022-06-02 13:33:10 -0700 |
---|---|---|
committer | Peter Klausler <pklausler@nvidia.com> | 2022-06-04 09:55:53 -0700 |
commit | 11f928af9bfaefc0965a43f5ad6d480ded3de4a5 (patch) | |
tree | c989a32bc94adaa5c581bf29949daab7b318b02d | |
parent | ed71a0b45b6c927333fa2c91e16f75a251408691 (diff) | |
download | llvm-11f928af9bfaefc0965a43f5ad6d480ded3de4a5.zip llvm-11f928af9bfaefc0965a43f5ad6d480ded3de4a5.tar.gz llvm-11f928af9bfaefc0965a43f5ad6d480ded3de4a5.tar.bz2 |
[flang][runtime] Fix deadlock in error recovery
When an external I/O statement is in a recoverable error
state before any data transfers take place (for example,
an unformatted transfer with ERR=/IOSTAT=/IOMSG= attempted on
a formatted unit), ensure that the unit's mutex is still
released at the end of the statement.
Differential Revision: https://reviews.llvm.org/D127032
-rw-r--r-- | flang/runtime/io-api.cpp | 12 | ||||
-rw-r--r-- | flang/runtime/io-stmt.cpp | 3 | ||||
-rw-r--r-- | flang/runtime/io-stmt.h | 8 |
3 files changed, 14 insertions, 9 deletions
diff --git a/flang/runtime/io-api.cpp b/flang/runtime/io-api.cpp index a50f011..b706007 100644 --- a/flang/runtime/io-api.cpp +++ b/flang/runtime/io-api.cpp @@ -172,7 +172,7 @@ Cookie BeginExternalListIO( *child, sourceFile, sourceLine); } else { return &child->BeginIoStatement<ErroneousIoStatementState>( - iostat, sourceFile, sourceLine); + iostat, nullptr /* no unit */, sourceFile, sourceLine); } } else { if (iostat == IostatOk && unit.access == Access::Direct) { @@ -186,7 +186,7 @@ Cookie BeginExternalListIO( std::forward<A>(xs)..., unit, sourceFile, sourceLine); } else { return &unit.BeginIoStatement<ErroneousIoStatementState>( - iostat, sourceFile, sourceLine); + iostat, &unit, sourceFile, sourceLine); } } } @@ -228,7 +228,7 @@ Cookie BeginExternalFormattedIO(const char *format, std::size_t formatLength, *child, format, formatLength, sourceFile, sourceLine); } else { return &child->BeginIoStatement<ErroneousIoStatementState>( - iostat, sourceFile, sourceLine); + iostat, nullptr /* no unit */, sourceFile, sourceLine); } } else { if (iostat == IostatOk) { @@ -239,7 +239,7 @@ Cookie BeginExternalFormattedIO(const char *format, std::size_t formatLength, unit, format, formatLength, sourceFile, sourceLine); } else { return &unit.BeginIoStatement<ErroneousIoStatementState>( - iostat, sourceFile, sourceLine); + iostat, &unit, sourceFile, sourceLine); } } } @@ -280,7 +280,7 @@ Cookie BeginUnformattedIO( *child, sourceFile, sourceLine); } else { return &child->BeginIoStatement<ErroneousIoStatementState>( - iostat, sourceFile, sourceLine); + iostat, nullptr /* no unit */, sourceFile, sourceLine); } } else { if (iostat == IostatOk) { @@ -301,7 +301,7 @@ Cookie BeginUnformattedIO( return &io; } else { return &unit.BeginIoStatement<ErroneousIoStatementState>( - iostat, sourceFile, sourceLine); + iostat, &unit, sourceFile, sourceLine); } } } diff --git a/flang/runtime/io-stmt.cpp b/flang/runtime/io-stmt.cpp index c3dab05..b29ab15 100644 --- a/flang/runtime/io-stmt.cpp +++ b/flang/runtime/io-stmt.cpp @@ -1520,6 +1520,9 @@ bool InquireIOLengthState::Emit(const char32_t *p, std::size_t n) { int ErroneousIoStatementState::EndIoStatement() { SignalPendingError(); + if (unit_) { + unit_->EndIoStatement(); + } return IoStatementBase::EndIoStatement(); } diff --git a/flang/runtime/io-stmt.h b/flang/runtime/io-stmt.h index 16a0e03..5a5bef5 100644 --- a/flang/runtime/io-stmt.h +++ b/flang/runtime/io-stmt.h @@ -711,9 +711,10 @@ private: class ErroneousIoStatementState : public IoStatementBase { public: - explicit ErroneousIoStatementState( - Iostat iostat, const char *sourceFile = nullptr, int sourceLine = 0) - : IoStatementBase{sourceFile, sourceLine} { + explicit ErroneousIoStatementState(Iostat iostat, + ExternalFileUnit *unit = nullptr, const char *sourceFile = nullptr, + int sourceLine = 0) + : IoStatementBase{sourceFile, sourceLine}, unit_{unit} { SetPendingError(iostat); } int EndIoStatement(); @@ -722,6 +723,7 @@ public: private: ConnectionState connection_; + ExternalFileUnit *unit_{nullptr}; }; extern template bool IoStatementState::EmitEncoded<char>( |