File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -123,6 +123,18 @@ pub(crate) fn server_has_newer_binary() -> bool {
123123 }
124124
125125 candidates. into_iter ( ) . any ( |candidate| {
126+ // If the candidate canonicalizes to the same file as the running binary,
127+ // there is by definition no newer binary to reload into. Without this
128+ // guard, a stable channel symlink that points back at the running
129+ // versioned binary (or a release whose mtime was bumped after process
130+ // start, e.g. by a re-install) would drive an infinite reload loop.
131+ // See issues #157, #160 and the `hash=unknown` reload symptom.
132+ if let Some ( current_canon) = current_canonical. as_ref ( )
133+ && current_canon == & candidate
134+ {
135+ return false ;
136+ }
137+
126138 let candidate_mtime = std:: fs:: metadata ( & candidate)
127139 . ok ( )
128140 . and_then ( |m| m. modified ( ) . ok ( ) ) ;
Original file line number Diff line number Diff line change @@ -155,6 +155,20 @@ impl App {
155155 return false ;
156156 } ;
157157
158+ // Same fix as server_has_newer_binary: if the candidate file
159+ // canonicalizes to the same path as the currently running binary,
160+ // there is nothing to reload into. This prevents the infinite
161+ // reload loop reported in issues #157 and #160 where the stable
162+ // channel resolves back to the running versioned binary but with
163+ // a freshly-bumped mtime (e.g. after a re-install).
164+ if let Ok ( candidate_canon) = std:: fs:: canonicalize ( & candidate)
165+ && let Ok ( current_exe) = std:: env:: current_exe ( )
166+ && let Ok ( current_canon) = std:: fs:: canonicalize ( & current_exe)
167+ && candidate_canon == current_canon
168+ {
169+ return false ;
170+ }
171+
158172 std:: fs:: metadata ( & candidate)
159173 . ok ( )
160174 . and_then ( |m| m. modified ( ) . ok ( ) )
You can’t perform that action at this time.
0 commit comments