[flang-commits] [flang] 11f928a - [flang][runtime] Fix deadlock in error recovery

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Sat Jun 4 11:02:25 PDT 2022


Author: Peter Klausler
Date: 2022-06-04T09:55:53-07:00
New Revision: 11f928af9bfaefc0965a43f5ad6d480ded3de4a5

URL: https://github.com/llvm/llvm-project/commit/11f928af9bfaefc0965a43f5ad6d480ded3de4a5
DIFF: https://github.com/llvm/llvm-project/commit/11f928af9bfaefc0965a43f5ad6d480ded3de4a5.diff

LOG: [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

Added: 
    

Modified: 
    flang/runtime/io-api.cpp
    flang/runtime/io-stmt.cpp
    flang/runtime/io-stmt.h

Removed: 
    


################################################################################
diff  --git a/flang/runtime/io-api.cpp b/flang/runtime/io-api.cpp
index a50f01131b7a..b7060076ad11 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 c3dab0506825..b29ab1524be2 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 16a0e031403f..5a5bef5d4e61 100644
--- a/flang/runtime/io-stmt.h
+++ b/flang/runtime/io-stmt.h
@@ -711,9 +711,10 @@ class ExternalMiscIoStatementState : public ExternalIoStatementBase {
 
 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 @@ class ErroneousIoStatementState : public IoStatementBase {
 
 private:
   ConnectionState connection_;
+  ExternalFileUnit *unit_{nullptr};
 };
 
 extern template bool IoStatementState::EmitEncoded<char>(


        


More information about the flang-commits mailing list