Skip to content

Commit 11f928a

Browse files
committed
[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
1 parent ed71a0b commit 11f928a

File tree

3 files changed

+14
-9
lines changed

3 files changed

+14
-9
lines changed

flang/runtime/io-api.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ Cookie BeginExternalListIO(
172172
*child, sourceFile, sourceLine);
173173
} else {
174174
return &child->BeginIoStatement<ErroneousIoStatementState>(
175-
iostat, sourceFile, sourceLine);
175+
iostat, nullptr /* no unit */, sourceFile, sourceLine);
176176
}
177177
} else {
178178
if (iostat == IostatOk && unit.access == Access::Direct) {
@@ -186,7 +186,7 @@ Cookie BeginExternalListIO(
186186
std::forward<A>(xs)..., unit, sourceFile, sourceLine);
187187
} else {
188188
return &unit.BeginIoStatement<ErroneousIoStatementState>(
189-
iostat, sourceFile, sourceLine);
189+
iostat, &unit, sourceFile, sourceLine);
190190
}
191191
}
192192
}
@@ -228,7 +228,7 @@ Cookie BeginExternalFormattedIO(const char *format, std::size_t formatLength,
228228
*child, format, formatLength, sourceFile, sourceLine);
229229
} else {
230230
return &child->BeginIoStatement<ErroneousIoStatementState>(
231-
iostat, sourceFile, sourceLine);
231+
iostat, nullptr /* no unit */, sourceFile, sourceLine);
232232
}
233233
} else {
234234
if (iostat == IostatOk) {
@@ -239,7 +239,7 @@ Cookie BeginExternalFormattedIO(const char *format, std::size_t formatLength,
239239
unit, format, formatLength, sourceFile, sourceLine);
240240
} else {
241241
return &unit.BeginIoStatement<ErroneousIoStatementState>(
242-
iostat, sourceFile, sourceLine);
242+
iostat, &unit, sourceFile, sourceLine);
243243
}
244244
}
245245
}
@@ -280,7 +280,7 @@ Cookie BeginUnformattedIO(
280280
*child, sourceFile, sourceLine);
281281
} else {
282282
return &child->BeginIoStatement<ErroneousIoStatementState>(
283-
iostat, sourceFile, sourceLine);
283+
iostat, nullptr /* no unit */, sourceFile, sourceLine);
284284
}
285285
} else {
286286
if (iostat == IostatOk) {
@@ -301,7 +301,7 @@ Cookie BeginUnformattedIO(
301301
return &io;
302302
} else {
303303
return &unit.BeginIoStatement<ErroneousIoStatementState>(
304-
iostat, sourceFile, sourceLine);
304+
iostat, &unit, sourceFile, sourceLine);
305305
}
306306
}
307307
}

flang/runtime/io-stmt.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -1520,6 +1520,9 @@ bool InquireIOLengthState::Emit(const char32_t *p, std::size_t n) {
15201520

15211521
int ErroneousIoStatementState::EndIoStatement() {
15221522
SignalPendingError();
1523+
if (unit_) {
1524+
unit_->EndIoStatement();
1525+
}
15231526
return IoStatementBase::EndIoStatement();
15241527
}
15251528

flang/runtime/io-stmt.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -711,9 +711,10 @@ class ExternalMiscIoStatementState : public ExternalIoStatementBase {
711711

712712
class ErroneousIoStatementState : public IoStatementBase {
713713
public:
714-
explicit ErroneousIoStatementState(
715-
Iostat iostat, const char *sourceFile = nullptr, int sourceLine = 0)
716-
: IoStatementBase{sourceFile, sourceLine} {
714+
explicit ErroneousIoStatementState(Iostat iostat,
715+
ExternalFileUnit *unit = nullptr, const char *sourceFile = nullptr,
716+
int sourceLine = 0)
717+
: IoStatementBase{sourceFile, sourceLine}, unit_{unit} {
717718
SetPendingError(iostat);
718719
}
719720
int EndIoStatement();
@@ -722,6 +723,7 @@ class ErroneousIoStatementState : public IoStatementBase {
722723

723724
private:
724725
ConnectionState connection_;
726+
ExternalFileUnit *unit_{nullptr};
725727
};
726728

727729
extern template bool IoStatementState::EmitEncoded<char>(

0 commit comments

Comments
 (0)