(
object: isize,
completion_port: isize,
overlapped: usize,
timeout: u32,
vm: &VirtualMachine,
)
| 1740 | |
| 1741 | #[pyfunction] |
| 1742 | fn RegisterWaitWithQueue( |
| 1743 | object: isize, |
| 1744 | completion_port: isize, |
| 1745 | overlapped: usize, |
| 1746 | timeout: u32, |
| 1747 | vm: &VirtualMachine, |
| 1748 | ) -> PyResult<isize> { |
| 1749 | use windows_sys::Win32::System::Threading::{ |
| 1750 | RegisterWaitForSingleObject, WT_EXECUTEINWAITTHREAD, WT_EXECUTEONLYONCE, |
| 1751 | }; |
| 1752 | |
| 1753 | let data = alloc::sync::Arc::new(PostCallbackData { |
| 1754 | completion_port: completion_port as HANDLE, |
| 1755 | overlapped: overlapped as *mut OVERLAPPED, |
| 1756 | }); |
| 1757 | |
| 1758 | // Create raw pointer for the callback - this increments refcount |
| 1759 | let data_ptr = alloc::sync::Arc::into_raw(data.clone()); |
| 1760 | |
| 1761 | let mut new_wait_object: HANDLE = core::ptr::null_mut(); |
| 1762 | let ret = unsafe { |
| 1763 | RegisterWaitForSingleObject( |
| 1764 | &mut new_wait_object, |
| 1765 | object as HANDLE, |
| 1766 | Some(post_to_queue_callback), |
| 1767 | data_ptr as *mut _, |
| 1768 | timeout, |
| 1769 | WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE, |
| 1770 | ) |
| 1771 | }; |
| 1772 | |
| 1773 | if ret == 0 { |
| 1774 | // Registration failed - reconstruct Arc to drop the extra reference |
| 1775 | unsafe { |
| 1776 | let _ = alloc::sync::Arc::from_raw(data_ptr); |
| 1777 | } |
| 1778 | return Err(set_from_windows_err(0, vm)); |
| 1779 | } |
| 1780 | |
| 1781 | // Store in registry for cleanup tracking |
| 1782 | let wait_handle = new_wait_object as isize; |
| 1783 | if let Ok(mut registry) = wait_callback_registry().lock() { |
| 1784 | registry.insert(wait_handle, data); |
| 1785 | } |
| 1786 | |
| 1787 | Ok(wait_handle) |
| 1788 | } |
| 1789 | |
| 1790 | // Helper to cleanup callback data when unregistering |
| 1791 | // Just removes from registry - Arc ensures memory stays alive if callback is running |
nothing calls this directly
no test coverage detected