aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Klausler <pklausler@nvidia.com>2022-06-02 13:33:10 -0700
committerPeter Klausler <pklausler@nvidia.com>2022-06-04 09:55:53 -0700
commit11f928af9bfaefc0965a43f5ad6d480ded3de4a5 (patch)
treec989a32bc94adaa5c581bf29949daab7b318b02d
parented71a0b45b6c927333fa2c91e16f75a251408691 (diff)
downloadllvm-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.cpp12
-rw-r--r--flang/runtime/io-stmt.cpp3
-rw-r--r--flang/runtime/io-stmt.h8
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>(