Fix unsafe thread-safety docs for cursor handles

This commit is contained in:
2025-05-30 22:38:50 -05:00
parent bba65f2f97
commit a9976cbbe5
3 changed files with 28 additions and 2 deletions
+11
View File
@@ -2,6 +2,13 @@ use std::path::PathBuf;
use image::RgbaImage;
// Windows-specific cursor handle wrapper
//
// SAFETY: This wrapper around HCURSOR implements Send for the same reasons as SyncHCURSOR:
// Windows cursor handles are reference-counted by the kernel and safe to transfer between threads.
// The handle value is just a pointer-sized integer that represents a kernel resource.
//
// NOTE: This type serves a similar purpose to SyncHCURSOR in windows/types.rs but is used
// for cross-platform compatibility. Consider consolidating these types in the future.
#[cfg(target_os = "windows")]
#[derive(Debug, Clone, Copy)]
pub struct WinCursorWrapper {
@@ -11,6 +18,10 @@ pub struct WinCursorWrapper {
#[cfg(target_os = "windows")]
unsafe impl Send for WinCursorWrapper {}
// NOTE: WinCursorWrapper doesn't implement Sync because it's only used for transferring
// cursor handles between threads, not for sharing them. If Sync is needed in the future,
// it would be safe to implement for the same reasons as Send.
// Common type for cursor information
#[derive(Debug, Clone)]
pub struct CursorInfo {
@@ -9,9 +9,24 @@ use winapi::{
// --- Thread-Safe Handle Wrappers ---
// These wrappers make raw Windows handles safe to share between threads
// Wrapper for HCURSOR (cursor handle)
// Wrapper for HCURSOR (cursor handle) that implements Send + Sync
//
// SAFETY: HCURSOR is a Windows handle that represents a cursor resource.
// Windows cursor handles are:
// 1. Reference-counted by the Windows kernel
// 2. Safe to share between threads (multiple threads can hold the same handle)
// 3. Safe to send between threads (the handle value itself is just a pointer-sized integer)
// 4. Immutable once created (cursor resources don't change after creation)
//
// The Windows API documentation confirms that cursor handles can be used from any thread,
// and the kernel manages the underlying resource lifetime through reference counting.
// Therefore, it's safe to implement Send + Sync for this wrapper.
//
// NOTE: The caller is responsible for ensuring proper cleanup (calling DestroyIcon)
// to avoid resource leaks, but this doesn't affect thread safety.
#[derive(Copy, Clone, Debug)]
pub struct SyncHCURSOR(pub HCURSOR);
unsafe impl Send for SyncHCURSOR {}
unsafe impl Sync for SyncHCURSOR {}