Files
lmxopcua/tests/Drivers
Joseph Doherty 4c4dfaadcc fix(focas): recycle the device handle under ConnectGate and drain it first (R07:L6)
The handle-recycle loop disposed the device client with no gate. It could null a client a
concurrent EnsureConnectedAsync had just installed (orphaning a live two-socket session),
or dispose one a poll was mid-read on (ObjectDisposedException -> BadCommunicationError +
Degraded on every recycle interval).

The recycle now takes the device's ConnectGate, detaches the client, and disposes it via
SynchronizedFocasClient.DisposeWhenIdleAsync, which waits (bounded by the call timeout plus
slack) for ops that already hold the client. The gate stays held through the drain, so no
fresh session opens beside the old one.

SynchronizedFocasClient no longer disposes its call gate. Releasing a disposed semaphore
threw out of reads that had otherwise completed. Ops that reach a disposed client now get
ObjectDisposedException and are never run on the dead socket.

Refs #740
Claude-Session: https://claude.ai/code/session_01Ub9hGmYLQvn9XETzw7CMsT
2026-10-22 14:21:02 -04:00
..