Skip to content

Conversation

@youknowone
Copy link
Member

@youknowone youknowone commented Dec 25, 2025

Summary by CodeRabbit

  • New Features
    • Enhanced Windows API support including named pipe operations, event object management, and file write capabilities for Python scripts.
    • Implemented batched multi-object waiting functionality to handle more than 64 concurrent operations simultaneously with timeout and synchronization options.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 25, 2025

📝 Walkthrough

Walkthrough

Six new Windows API Python-callable wrappers were added to the stdlib module: named pipe utilities (WaitNamedPipe, PeekNamedPipe), event management (CreateEventW, SetEvent), file I/O (WriteFile), and a sophisticated BatchedWaitForMultipleObjects function that batches handle waiting, manages thread coordination, and handles timeouts across multiple handle groups.

Changes

Cohort / File(s) Summary
Named Pipe Utilities
crates/vm/src/stdlib/winapi.rs
Added WaitNamedPipe() to wait for pipe availability with timeout and PeekNamedPipe() to query pipe status and read peek data without consuming it.
Event Management
crates/vm/src/stdlib/winapi.rs
Added CreateEventW() to create manual or automatic reset event objects with optional naming, and SetEvent() to signal event state.
File I/O Operations
crates/vm/src/stdlib/winapi.rs
Added WriteFile() wrapper supporting buffer writing with optional overlapped I/O flag, returning bytes written and error code.
Multi-Handle Waiting
crates/vm/src/stdlib/winapi.rs
Implemented BatchedWaitForMultipleObjects() with complex control flow: batches handles (max 64 per batch), supports wait_all/wait_any modes, manages timeouts via cancel events, spawns coordinating threads, and collects triggered handle indices.
Comment Refinement
crates/vm/src/stdlib/winapi.rs
Minor wording adjustment in LCMapStringEx rejection comment; behavior unchanged.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant BatchedWait as BatchedWaitForMultipleObjects
    participant Batcher as Batching Logic
    participant Thread as Worker Threads
    participant WinAPI as Windows API
    participant Events as Event Objects
    
    Client->>BatchedWait: call with handles, wait_all, timeout
    BatchedWait->>Events: create cancel_event
    
    rect rgb(220, 240, 255)
    note over BatchedWait,Batcher: Batching Phase
    BatchedWait->>Batcher: partition handles into groups (≤64 each)
    end
    
    rect rgb(240, 220, 255)
    note over Thread,WinAPI: Parallel Waiting Phase
    par Per-Batch Processing
        Batcher->>Thread: spawn worker thread for batch
        Thread->>WinAPI: WaitForMultipleObjects(batch + cancel_event)
        WinAPI-->>Thread: returns triggered index or timeout
        Thread->>Thread: collect result & triggered indices
    end
    end
    
    rect rgb(240, 255, 220)
    note over BatchedWait,Thread: Coordination & Cleanup
    alt timeout elapsed
        BatchedWait->>Events: signal cancel_event
        Thread->>Thread: abort wait, cleanup
    end
    BatchedWait->>BatchedWait: collect all thread results
    BatchedWait->>BatchedWait: build return (status + indices)
    end
    
    BatchedWait-->>Client: return PyObjectRef (result tuple)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • ShaharNaveh

Poem

🐰 Whiskers twitching with delight,
New event loops shimmer bright!
Batched handles dance in sync,
Threading threads in coordinated link,
Windows API dreams come alive tonight!

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'impl more winapi' is overly vague and does not clearly convey the specific changes being made. Use a more descriptive title that specifies which Windows API functions are being added, such as 'Add Windows event and named pipe functions to stdlib'
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@youknowone youknowone marked this pull request as ready for review December 25, 2025 15:49
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
crates/vm/src/stdlib/winapi.rs (2)

1002-1028: Add safety comments for unsafe trait implementations.

The unsafe impl Send and unsafe impl Sync for BatchData are correct given the access patterns, but the safety invariants should be documented to prevent future maintenance issues.

🔎 Suggested documentation
+            // SAFETY: BatchData is Send because all fields are either Send or are only accessed
+            // from the main thread (thread field is written before threads start, read after they finish).
             unsafe impl Send for BatchData {}
+            // SAFETY: BatchData is Sync because:
+            // - handles, cancel_event, handle_base are immutable after construction
+            // - result uses AtomicU32 for synchronization
+            // - thread (UnsafeCell) is only accessed from the main thread: written after
+            //   CreateThread but before ResumeThread, read only after threads complete
             unsafe impl Sync for BatchData {}

1062-1084: Consider using 0 for default stack size.

The stack size of 1 at line 1066 works (Windows rounds up to minimum), but using 0 is more conventional and explicitly requests the default stack size for the executable.

🔎 Suggested change
                 let thread = unsafe {
                     CreateThread(
                         null(),
-                        1, // Smallest stack
+                        0, // Default stack size
                         Some(batch_wait_thread),
                         Arc::as_ptr(data) as *const _ as *mut _,
                         4, // CREATE_SUSPENDED
                         null_mut(),
                     )
                 };
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2063c1e and 3edda7b.

⛔ Files ignored due to path filters (1)
  • Lib/test/test_winapi.py is excluded by !Lib/**
📒 Files selected for processing (1)
  • crates/vm/src/stdlib/winapi.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.rs: Follow the default rustfmt code style by running cargo fmt to format Rust code
Always run clippy to lint Rust code (cargo clippy) before completing tasks and fix any warnings or lints introduced by changes
Follow Rust best practices for error handling and memory management
Use the macro system (pyclass, pymodule, pyfunction, etc.) when implementing Python functionality in Rust

Files:

  • crates/vm/src/stdlib/winapi.rs
🧬 Code graph analysis (1)
crates/vm/src/stdlib/winapi.rs (1)
crates/stdlib/src/overlapped.rs (1)
  • SetEvent (398-404)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Run snippets and cpython tests (macos-latest)
  • GitHub Check: Run snippets and cpython tests (ubuntu-latest)
  • GitHub Check: Run snippets and cpython tests (windows-latest)
🔇 Additional comments (9)
crates/vm/src/stdlib/winapi.rs (9)

729-743: LGTM!

Clean implementation following the established pattern in this module.


745-809: LGTM!

Good validation of negative size and proper handling of both read and peek-only modes.


811-841: LGTM!

The security_attributes parameter is intentionally ignored to maintain API compatibility while using NULL security attributes, which is the common case.


843-855: LGTM!

Correct implementation. Note that overlapped.rs has a similar SetEvent that accepts u64 handles - both are valid for their respective module conventions.


857-900: LGTM!

Clean implementation with proper error handling. The early return on error at line 895-897 ensures the success case correctly returns (written, 0).


902-953: LGTM!

The batching logic correctly handles the Windows MAXIMUM_WAIT_OBJECTS limit by reserving one slot per batch for the cancel event.


955-994: LGTM!

The sequential batch waiting with deadline tracking correctly handles timeouts across multiple batches.


1030-1058: LGTM!

The thread function correctly handles all wait outcomes and uses proper atomic ordering for the result.


1091-1163: LGTM!

The cleanup logic correctly ensures all threads complete before closing handles, and the triggered index collection properly excludes the cancel event.

@youknowone youknowone merged commit 21f24cd into RustPython:main Dec 25, 2025
12 of 13 checks passed
@youknowone youknowone deleted the winapi branch December 25, 2025 16:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant