Skip to content

Commit 699b857

Browse files
committed
Try to detect stale type changes when hotpatching
1 parent c1c5fbd commit 699b857

2 files changed

Lines changed: 72 additions & 14 deletions

File tree

debug/src/lib.rs

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ pub fn on_hotpatch(f: impl Fn() + Send + Sync + 'static) {
121121
internal::on_hotpatch(f)
122122
}
123123

124+
pub fn is_stale() -> bool {
125+
internal::is_stale()
126+
}
127+
124128
#[cfg(all(feature = "enable", not(target_arch = "wasm32")))]
125129
mod internal {
126130
use crate::core::theme;
@@ -136,8 +140,16 @@ mod internal {
136140
use beacon::span;
137141
use beacon::span::present;
138142

143+
use std::collections::BTreeSet;
139144
use std::sync::atomic::{self, AtomicBool, AtomicUsize};
140-
use std::sync::{Arc, LazyLock, RwLock};
145+
use std::sync::{Arc, LazyLock, Mutex, OnceLock, RwLock};
146+
147+
static IS_STALE: AtomicBool = AtomicBool::new(false);
148+
149+
static HOT_FUNCTIONS_PENDING: Mutex<BTreeSet<u64>> =
150+
Mutex::new(BTreeSet::new());
151+
152+
static HOT_FUNCTIONS: OnceLock<BTreeSet<u64>> = OnceLock::new();
141153

142154
pub fn init(metadata: Metadata) {
143155
let name = metadata.name.split("::").next().unwrap_or(metadata.name);
@@ -150,6 +162,20 @@ mod internal {
150162
};
151163

152164
cargo_hot::connect();
165+
166+
cargo_hot::subsecond::register_handler(Arc::new(|| {
167+
if HOT_FUNCTIONS.get().is_none() {
168+
HOT_FUNCTIONS
169+
.set(std::mem::take(
170+
&mut HOT_FUNCTIONS_PENDING
171+
.lock()
172+
.expect("Lock hot functions"),
173+
))
174+
.expect("Set hot functions");
175+
}
176+
177+
IS_STALE.store(false, atomic::Ordering::Relaxed);
178+
}));
153179
}
154180

155181
pub fn quit() -> bool {
@@ -286,15 +312,34 @@ mod internal {
286312

287313
// The `move` here is important. Hotpatching will not work
288314
// otherwise.
289-
cargo_hot::subsecond::call(move || {
315+
let mut f = cargo_hot::subsecond::HotFn::current(move || {
290316
f.take().expect("Hot function is stale")()
291-
})
317+
});
318+
319+
let address = f.ptr_address().0;
320+
321+
if let Some(hot_functions) = HOT_FUNCTIONS.get() {
322+
if hot_functions.contains(&address) {
323+
IS_STALE.store(true, atomic::Ordering::Relaxed);
324+
}
325+
} else {
326+
let _ = HOT_FUNCTIONS_PENDING
327+
.lock()
328+
.expect("Lock hot functions")
329+
.insert(address);
330+
}
331+
332+
f.call(())
292333
}
293334

294335
pub fn on_hotpatch(f: impl Fn() + Send + Sync + 'static) {
295336
cargo_hot::subsecond::register_handler(Arc::new(f));
296337
}
297338

339+
pub fn is_stale() -> bool {
340+
IS_STALE.load(atomic::Ordering::Relaxed)
341+
}
342+
298343
fn span(span: span::Stage) -> Span {
299344
log(client::Event::SpanStarted(span.clone()));
300345

@@ -428,4 +473,8 @@ mod internal {
428473
}
429474

430475
pub fn on_hotpatch(_f: impl Fn() + Send + Sync + 'static) {}
476+
477+
pub fn is_stale() -> bool {
478+
false
479+
}
431480
}

devtools/src/lib.rs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -343,21 +343,30 @@ where
343343
themer(derive_theme(), Element::from(mode).map(Event::Message))
344344
});
345345

346-
let notification = self.show_notification.then(|| {
347-
themer(
348-
derive_theme(),
349-
bottom_right(opaque(
350-
container(text("Press F12 to open debug metrics"))
351-
.padding(10)
352-
.style(container::dark),
353-
)),
354-
)
355-
});
346+
let notification = self
347+
.show_notification
348+
.then(|| text("Press F12 to open debug metrics"))
349+
.or_else(|| {
350+
debug::is_stale().then(|| {
351+
text(
352+
"Types have changed. Restart to re-enable hotpatching.",
353+
)
354+
})
355+
});
356356

357357
stack![view]
358358
.height(Fill)
359359
.push_maybe(mode.map(opaque))
360-
.push_maybe(notification)
360+
.push_maybe(notification.map(|notification| {
361+
themer(
362+
derive_theme(),
363+
bottom_right(opaque(
364+
container(notification)
365+
.padding(10)
366+
.style(container::dark),
367+
)),
368+
)
369+
}))
361370
.into()
362371
}
363372

0 commit comments

Comments
 (0)