Replace mutex unwraps with proper error handling

This commit is contained in:
2025-05-30 23:10:43 -05:00
parent 4f71789710
commit 09374eecb3
@@ -197,12 +197,28 @@ unsafe fn create_cursor_from_image(image: &RgbaImage) -> Option<SyncHCURSOR> {
Some(SyncHCURSOR(cursor)) Some(SyncHCURSOR(cursor))
} }
// Helper function to safely lock a mutex with error handling
fn safe_lock<'a, T>(mutex: &'a std::sync::Mutex<T>, operation_name: &str) -> Option<std::sync::MutexGuard<'a, T>> {
match mutex.lock() {
Ok(guard) => Some(guard),
Err(poisoned) => {
eprintln!("Mutex poisoned during {}: {}", operation_name, poisoned);
// For cleanup operations, we can still try to recover the data
Some(poisoned.into_inner())
}
}
}
// Cleanup function to restore cursors and clean up resources // Cleanup function to restore cursors and clean up resources
pub fn cleanup() { pub fn cleanup() {
// Check if we have original cursors saved before attempting restoration // Check if we have original cursors saved before attempting restoration
let has_original_cursors = { let _has_original_cursors = {
let guard = ORIGINAL_CURSORS.lock().unwrap(); if let Some(guard) = safe_lock(&ORIGINAL_CURSORS, "checking original cursors") {
guard.is_some() guard.is_some()
} else {
eprintln!("Failed to check original cursors during cleanup");
false
}
}; };
// Restore system cursors if they were hidden // Restore system cursors if they were hidden
@@ -214,8 +230,12 @@ pub fn cleanup() {
// 1. First try to restore original cursors if we saved them // 1. First try to restore original cursors if we saved them
let original_cursors_opt = { let original_cursors_opt = {
let mut guard = ORIGINAL_CURSORS.lock().unwrap(); if let Some(mut guard) = safe_lock(&ORIGINAL_CURSORS, "restoring original cursors") {
guard.take() guard.take()
} else {
eprintln!("Failed to access original cursors for restoration");
None
}
}; };
if let Some(original_cursors) = original_cursors_opt { if let Some(original_cursors) = original_cursors_opt {
@@ -268,7 +288,13 @@ pub fn cleanup() {
} }
// Destroy the custom cursor if it exists // Destroy the custom cursor if it exists
let custom_cursor_to_destroy = CUSTOM_CURSOR.lock().unwrap().take(); let custom_cursor_to_destroy = if let Some(mut guard) = safe_lock(&CUSTOM_CURSOR, "destroying custom cursor") {
guard.take()
} else {
eprintln!("Failed to access custom cursor for cleanup");
None
};
if let Some(cursor_wrapper) = custom_cursor_to_destroy { if let Some(cursor_wrapper) = custom_cursor_to_destroy {
unsafe { unsafe {
if !cursor_wrapper.0.is_null() { if !cursor_wrapper.0.is_null() {
@@ -278,10 +304,18 @@ pub fn cleanup() {
} }
// Reset the last known cursor position // Reset the last known cursor position
*LAST_CURSOR_POS.lock().unwrap() = None; if let Some(mut guard) = safe_lock(&LAST_CURSOR_POS, "resetting cursor position") {
*guard = None;
} else {
eprintln!("Failed to reset cursor position during cleanup");
}
// Clear the current cursor image // Clear the current cursor image
*CURRENT_CURSOR_IMAGE.lock().unwrap() = None; if let Some(mut guard) = safe_lock(&CURRENT_CURSOR_IMAGE, "clearing cursor image") {
*guard = None;
} else {
eprintln!("Failed to clear cursor image during cleanup");
}
// Unregister control handler // Unregister control handler
if CTRL_HANDLER_REGISTERED.load(Ordering::SeqCst) { if CTRL_HANDLER_REGISTERED.load(Ordering::SeqCst) {
@@ -333,7 +367,11 @@ pub fn hide_system_cursor() -> bool {
// Store original cursors for restoration // Store original cursors for restoration
if !original_cursors.is_empty() { if !original_cursors.is_empty() {
*ORIGINAL_CURSORS.lock().unwrap() = Some(original_cursors); if let Some(mut guard) = safe_lock(&ORIGINAL_CURSORS, "storing original cursors") {
*guard = Some(original_cursors);
} else {
eprintln!("Failed to store original cursors for restoration");
}
} else { } else {
eprintln!("No original cursors were saved!"); eprintln!("No original cursors were saved!");
} }
@@ -368,7 +406,11 @@ pub fn update_cursor_info(cursor_info: &mut crate::platform::types::CursorInfo)
}; };
// Store the image in the global state for reference // Store the image in the global state for reference
*CURRENT_CURSOR_IMAGE.lock().unwrap() = Some(image.clone()); if let Some(mut guard) = safe_lock(&CURRENT_CURSOR_IMAGE, "storing cursor image") {
*guard = Some(image.clone());
} else {
eprintln!("Failed to store cursor image in global state");
}
unsafe { unsafe {
// Create a new cursor first before destroying the old one // Create a new cursor first before destroying the old one
@@ -385,14 +427,20 @@ pub fn update_cursor_info(cursor_info: &mut crate::platform::types::CursorInfo)
let success = apply_cursor_to_all_system_cursors(new_cursor_wrapper.0); let success = apply_cursor_to_all_system_cursors(new_cursor_wrapper.0);
// Now that the new cursor is applied, we can clean up the old one // Now that the new cursor is applied, we can clean up the old one
let mut cursor_guard = CUSTOM_CURSOR.lock().unwrap(); if let Some(mut cursor_guard) = safe_lock(&CUSTOM_CURSOR, "updating custom cursor") {
if let Some(old_cursor) = cursor_guard.take() { if let Some(old_cursor) = cursor_guard.take() {
// Only destroy the old cursor after the new one is applied // Only destroy the old cursor after the new one is applied
DestroyIcon(old_cursor.0); DestroyIcon(old_cursor.0);
} }
// Store the new cursor // Store the new cursor
*cursor_guard = Some(new_cursor_wrapper); *cursor_guard = Some(new_cursor_wrapper);
} else {
eprintln!("Failed to update custom cursor - mutex lock failed");
// Clean up the new cursor since we can't store it
DestroyIcon(new_cursor_wrapper.0);
return false;
}
// Update the cached cursor in CursorInfo // Update the cached cursor in CursorInfo
#[cfg(windows)] #[cfg(windows)]
@@ -417,12 +465,15 @@ pub fn update_cursor_info(cursor_info: &mut crate::platform::types::CursorInfo)
#[cfg(windows)] #[cfg(windows)]
if let Some(cached_cursor) = &cursor_info.win_cursor { if let Some(cached_cursor) = &cursor_info.win_cursor {
if !cached_cursor.handle.is_null() { if !cached_cursor.handle.is_null() {
let mut cursor_guard = CUSTOM_CURSOR.lock().unwrap(); if let Some(mut cursor_guard) = safe_lock(&CUSTOM_CURSOR, "using cached cursor fallback") {
// Convert WinCursorWrapper to SyncHCURSOR // Convert WinCursorWrapper to SyncHCURSOR
let sync_cursor = super::types::SyncHCURSOR(cached_cursor.handle); let sync_cursor = super::types::SyncHCURSOR(cached_cursor.handle);
*cursor_guard = Some(sync_cursor); *cursor_guard = Some(sync_cursor);
SetCursor(cached_cursor.handle); SetCursor(cached_cursor.handle);
return true; return true;
} else {
eprintln!("Failed to use cached cursor fallback - mutex lock failed");
}
} }
} }