fix(abcip): budget expected reply size in RequestScheduler.TakeBatch (#582); private lock + struct-handle check across read fragments (#567)
Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
@@ -175,11 +175,15 @@ internal sealed class NativeAbLegacyTagRuntime : IAbLegacyTagRuntime
|
||||
return (Math.Max(1, PcccServices.MaxDataBytes / _elementSize), address);
|
||||
}
|
||||
|
||||
private async Task<ReadOnlyMemory<byte>> ExchangeAsync(Func<ushort, byte[]> pccc, CancellationToken ct)
|
||||
/// <summary>Bytes of an Execute PCCC reply beyond its data: CIP header, requestor id, PCCC command / status / TNS
|
||||
/// (rounded up) — the scheduler budgets <c>PcccReplyOverhead + data</c> against the connection (#582).</summary>
|
||||
private const int PcccReplyOverhead = 32;
|
||||
|
||||
private async Task<ReadOnlyMemory<byte>> ExchangeAsync(Func<ushort, byte[]> pccc, CancellationToken ct, int replyDataBytes = 0)
|
||||
{
|
||||
var tns = unchecked((ushort)Interlocked.Increment(ref s_tns));
|
||||
var request = PcccServices.ExecutePccc(_vendor, _serial, pccc(tns));
|
||||
var reply = await _scheduler.SendAsync(request, ct).ConfigureAwait(false);
|
||||
var reply = await _scheduler.SendAsync(request, ct, expectedReplyBytes: PcccReplyOverhead + replyDataBytes).ConfigureAwait(false);
|
||||
return PcccServices.ParseReply(reply, tns, _requestorId);
|
||||
}
|
||||
|
||||
@@ -200,7 +204,7 @@ internal sealed class NativeAbLegacyTagRuntime : IAbLegacyTagRuntime
|
||||
tns => plc5
|
||||
? PcccServices.Plc5RangeRead(tns, at, (ushort)(bytes / 2), bytes)
|
||||
: PcccServices.SlcTypedRead(tns, at, bytes),
|
||||
ct).ConfigureAwait(false);
|
||||
ct, bytes).ConfigureAwait(false);
|
||||
if (data.Length < bytes)
|
||||
throw new AbTransportException(AbStatus.BadReply, $"PCCC read returned {data.Length} of {bytes} bytes.");
|
||||
if (data.Length > bytes)
|
||||
|
||||
Reference in New Issue
Block a user