Compare commits

...

2 Commits

Author SHA1 Message Date
dependabot[bot]
a6d6bf137d chore(deps): bump thiserror from 2.0.17 to 2.0.18
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 2.0.17 to 2.0.18.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/2.0.17...2.0.18)

---
updated-dependencies:
- dependency-name: thiserror
  dependency-version: 2.0.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-01-19 16:45:27 +00:00
Rejdukien
a335be9b84 fix(border): release resources before destroying window to prevent access violations
When a border is destroyed, the main thread was forcefully releasing D2D resources, while the border window thread might still be trying to use them in its message loop. Releasing the RenderTarget on one thread while another is calling EndDraw on it leads to a use-after-free scenario or invalid state for the COM object, resulting in the crash.

This commit applies a fix that moves the resource cleanup logic from the main thread to the window thread. Now, resources are only released during the WM_DESTROY message processing, which guarantees synchronization with other window messages like WM_PAINT.
2026-01-18 09:13:50 -08:00
3 changed files with 25 additions and 26 deletions

38
Cargo.lock generated
View File

@@ -587,7 +587,7 @@ dependencies = [
"num-traits",
"pastey",
"rayon",
"thiserror 2.0.17",
"thiserror 2.0.18",
"v_frame",
"y4m",
]
@@ -1684,7 +1684,7 @@ dependencies = [
"epaint",
"log",
"profiling",
"thiserror 2.0.17",
"thiserror 2.0.18",
"type-map",
"web-time",
"wgpu",
@@ -3280,7 +3280,7 @@ dependencies = [
"serde_json_lenient",
"shadow-rs",
"sysinfo 0.37.2",
"thiserror 2.0.17",
"thiserror 2.0.18",
"which",
"win-msgbox",
"windows 0.62.2",
@@ -3711,7 +3711,7 @@ dependencies = [
"once_cell",
"rustc-hash 1.1.0",
"spirv",
"thiserror 2.0.17",
"thiserror 2.0.18",
"unicode-ident",
]
@@ -5262,7 +5262,7 @@ dependencies = [
"rand 0.9.2",
"rand_chacha 0.9.0",
"simd_helpers",
"thiserror 2.0.17",
"thiserror 2.0.18",
"v_frame",
"wasm-bindgen",
]
@@ -5354,7 +5354,7 @@ checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
dependencies = [
"getrandom 0.2.16",
"libredox",
"thiserror 2.0.17",
"thiserror 2.0.18",
]
[[package]]
@@ -6032,7 +6032,7 @@ dependencies = [
"log",
"memmap2",
"rustix 1.1.3",
"thiserror 2.0.17",
"thiserror 2.0.18",
"wayland-backend",
"wayland-client",
"wayland-csd-frame",
@@ -6341,11 +6341,11 @@ dependencies = [
[[package]]
name = "thiserror"
version = "2.0.17"
version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
dependencies = [
"thiserror-impl 2.0.17",
"thiserror-impl 2.0.18",
]
[[package]]
@@ -6361,9 +6361,9 @@ dependencies = [
[[package]]
name = "thiserror-impl"
version = "2.0.17"
version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
dependencies = [
"proc-macro2",
"quote",
@@ -6622,7 +6622,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf"
dependencies = [
"crossbeam-channel",
"thiserror 2.0.17",
"thiserror 2.0.18",
"time",
"tracing-subscriber",
]
@@ -7208,7 +7208,7 @@ dependencies = [
"raw-window-handle",
"rustc-hash 1.1.0",
"smallvec",
"thiserror 2.0.17",
"thiserror 2.0.18",
"wgpu-core-deps-apple",
"wgpu-core-deps-emscripten",
"wgpu-core-deps-windows-linux-android",
@@ -7284,7 +7284,7 @@ dependencies = [
"raw-window-handle",
"renderdoc-sys",
"smallvec",
"thiserror 2.0.17",
"thiserror 2.0.18",
"wasm-bindgen",
"web-sys",
"wgpu-types",
@@ -7302,7 +7302,7 @@ dependencies = [
"bytemuck",
"js-sys",
"log",
"thiserror 2.0.17",
"thiserror 2.0.18",
"web-sys",
]
@@ -7328,7 +7328,7 @@ version = "0.2.10"
source = "git+https://github.com/LGUG2Z/whkd?rev=v0.2.10#5d6a767f2ab7ac309686fe44ce59689546cf55fe"
dependencies = [
"chumsky",
"thiserror 2.0.17",
"thiserror 2.0.18",
"whkd-core",
]
@@ -7348,7 +7348,7 @@ source = "git+https://github.com/LGUG2Z/win32-display-data?rev=8c42d8db257d30fe9
dependencies = [
"itertools",
"serde",
"thiserror 2.0.17",
"thiserror 2.0.18",
"windows 0.62.2",
"windows-core 0.62.2",
"wmi",
@@ -8211,7 +8211,7 @@ dependencies = [
"futures",
"log",
"serde",
"thiserror 2.0.17",
"thiserror 2.0.18",
"windows 0.60.0",
"windows-core 0.60.1",
]

View File

@@ -548,7 +548,12 @@ impl Border {
LRESULT(0)
}
WM_DESTROY => {
SetWindowLongPtrW(window, GWLP_USERDATA, 0);
let border_pointer: *mut Border = GetWindowLongPtrW(window, GWLP_USERDATA) as _;
if !border_pointer.is_null() {
(*border_pointer).render_target = None;
(*border_pointer).brushes.clear();
SetWindowLongPtrW(window, GWLP_USERDATA, 0);
}
PostQuitMessage(0);
LRESULT(0)
}

View File

@@ -767,12 +767,6 @@ fn remove_border(
fn destroy_border(border: Box<Border>) -> color_eyre::Result<()> {
let raw_pointer = Box::into_raw(border);
unsafe {
// release d2d resources **BEFORE** destroying window
// this drops render_target and brushes while HWND is still valid
// prevents EndDraw() from accessing freed HWND resources
(*raw_pointer).render_target = None;
(*raw_pointer).brushes.clear();
// Now safe to destroy window
(*raw_pointer).destroy()?;
}