Bind one FOCAS handle per path instead of mutating path state - #124
Open
deadman96385 wants to merge 1 commit into
Open
Bind one FOCAS handle per path instead of mutating path state#124deadman96385 wants to merge 1 commit into
deadman96385 wants to merge 1 commit into
Conversation
Platform held a single library handle and called cnc_setpath on it before every per-path read, mutating controller-global path state on each sweep. FANUC permits one thread to hold multiple handles for the same CNC (the library still opens only one TCP connection per process) and bind each handle to a path; this is the documented multi-path approach. Keep a dedicated handle per path: allocate and bind it with a single cnc_setpath the first time the path is selected, then just switch the selected handle on later reads. The single-path case is unchanged in cost because the primary connection handle is reused for the first path. Connect records the primary handle and clears stale ones; Disconnect frees every per-path handle exactly once. This eliminates the shared path-pointer races that the previous reset-to-first-path workaround only masked.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Platform holds a single library handle and calls cnc_setpath on it before every per-path read, mutating the controller-global path pointer on each sweep. This PR gives each path its own dedicated handle, bound once, so selecting a path becomes a handle swap rather than a global state mutation.
Background
This is the root cause behind #92 ("When option stay_connected=true, multi-path machines get stuck on last path") and its downstream report #103 (a DMG Mori 31i-B where only the last path's data flowed after a restart). Both were addressed by the "reset path on every iteration" workaround — re-issuing SetPath(0) each collect cycle to stop the shared handle from drifting to the last path.
That workaround masks the problem rather than removing it: the driver still keeps one handle and re-points it with cnc_setpath on every path switch, so the controller-global path pointer is shared across all reads and has to be defensively reset.
FOCAS actually supports a cleaner model. A handle is owned by the thread that created it, and FANUC explicitly permits one thread to hold multiple handles for the same CNC — binding each to a path — while the library still opens only a single TCP connection per process. It's quoted in the header comment of Platform.cs:
▎ "...on the 2 path control system, it is possible that the thread on an application gets two library handles for the same CNC ... and allocates the individual path to each handle."
What this changes
Platform now keeps a Dictionary<short, ushort> of path → handle plus the primary connection handle:
Because each handle carries its own path selection, the stay_connected=true multi-path scenario from #92/#103 is fixed structurally: handles persist across sweeps already bound to their paths, with no cnc_setpath re-issuing and nothing to reset.
Compatibility