fix(r2-01): cancellation observed mid-PDU marks the connection dead before propagating (STAB-15a, task 8)
This commit is contained in:
@@ -521,6 +521,17 @@ public sealed class S7Driver
|
||||
results[i] = new DataValueSnapshot(value, 0u, now, now);
|
||||
_health = new DriverHealth(DriverState.Healthy, now, null);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// Cancellation observed mid-PDU abandons a half-read ISO-on-TCP response on the
|
||||
// single gated stream — the handle must be reopened, not reused (STAB-15a). Mark
|
||||
// dead (we hold _gate) and propagate: the caller cancelled, nobody consumes the
|
||||
// batch. Marking is unconditional on OCE (not routed through the type classifier):
|
||||
// whether bytes moved is unknowable, and a false positive costs one cheap reopen
|
||||
// versus permanent desync for a false negative.
|
||||
_plcDead = true;
|
||||
throw;
|
||||
}
|
||||
catch (NotSupportedException)
|
||||
{
|
||||
results[i] = new DataValueSnapshot(null, StatusBadNotSupported, null, now);
|
||||
@@ -1057,8 +1068,12 @@ public sealed class S7Driver
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// Let cancellation propagate rather than turning it into
|
||||
// a status code — the gate is still held so Release() runs in finally.
|
||||
// Cancellation observed mid-PDU abandons a half-written ISO-on-TCP request on
|
||||
// the single gated stream — the handle must be reopened, not reused (STAB-15a).
|
||||
// Mark dead (we hold _gate) and propagate: the caller cancelled, nobody consumes
|
||||
// the batch, and Release() still runs in finally. Marking is unconditional on
|
||||
// OCE — a false positive costs one cheap reopen versus permanent desync.
|
||||
_plcDead = true;
|
||||
throw;
|
||||
}
|
||||
catch (NotSupportedException)
|
||||
|
||||
Reference in New Issue
Block a user