Hone logo
Hone
Problems

Asynchronous I/O Completion Port (IOCP) Wrapper in Rust

This challenge asks you to implement a basic wrapper around Windows' I/O Completion Ports (IOCP) in Rust. IOCPs provide a mechanism for asynchronous I/O operations, allowing a single thread to manage multiple I/O requests concurrently, significantly improving performance in I/O-bound applications. Your wrapper should provide a safe and idiomatic Rust interface for interacting with IOCPs.

Problem Description

You are tasked with creating a Rust library that encapsulates the core functionality of Windows IOCPs. The library should provide the following:

  1. IOCP Creation: A function to create a new IOCP. This function should handle potential errors during IOCP creation.
  2. File Mapping Association: A function to associate a file mapping object with the IOCP. This is crucial for receiving completion information related to file I/O.
  3. Post Completion Request: A function to post a completion request to the IOCP. This function should take a file handle and a completion key as input. The completion key will be used to identify the originating I/O request.
  4. Get Completion Port Status: A function to retrieve the number of completed I/O requests and clear the completion port. This function should handle potential errors during retrieval.
  5. Error Handling: Robust error handling throughout the library, converting Windows API errors into Rust Result types.

The library should be thread-safe, allowing multiple threads to post completion requests to the same IOCP. The core of the challenge lies in safely wrapping the Windows API calls and providing a clean, Rust-friendly interface.

Examples

Example 1:

Input:  None (IOCP creation)
Output: `Result<IOCP, WindowsError>` - `Ok(iocp_handle)`
Explanation:  A new IOCP is successfully created.

**Example 2:**

Input: `iocp_handle: IOCP, file_handle: HANDLE` (File Mapping Association)
Output: `Result<(), WindowsError>` - `Ok(())`
Explanation: The file handle is successfully associated with the IOCP.

**Example 3:**

Input: `iocp_handle: IOCP, file_handle: HANDLE, completion_key: u64` (Post Completion Request)
Output: `Result<(), WindowsError>` - `Ok(())`
Explanation: A completion request is successfully posted to the IOCP.

**Example 4:**

Input: `iocp_handle: IOCP` (Get Completion Port Status)
Output: `Result<(u32, u32), WindowsError>` - `Ok((1, 0))`
Explanation: One I/O operation has completed, and the number of bytes transferred is 0.

Constraints

  • The library must be compatible with Windows operating systems.
  • All Windows API calls must be wrapped using unsafe blocks, with appropriate safety checks to prevent memory corruption or undefined behavior.
  • The library should handle potential errors from the Windows API gracefully, returning appropriate Result types.
  • The IOCP creation and association functions should handle cases where the provided file handle is invalid.
  • The completion_key used in PostCompletionRequest should be a u64 to allow for sufficient identification of I/O requests.
  • The GetCompletionPortStatus function should return a tuple (num_completed_io, num_bytes_transferred).
  • The library should be designed to be extensible, allowing for future additions of functionality (e.g., asynchronous I/O operations).

Notes

  • You will need to use the windows-rs crate to access the Windows API. Ensure you have it added to your Cargo.toml.
  • Consider using std::sync::Mutex to protect shared resources (like the IOCP handle) from concurrent access.
  • The HANDLE type from windows-rs represents a Windows handle.
  • Think about how to represent the IOCP itself in Rust. A simple struct containing the IOCP handle is a good starting point.
  • Error handling is paramount. Carefully consider all potential failure points and provide informative error messages.
  • This is a foundational wrapper. You are not required to implement the full asynchronous I/O logic, only the IOCP management. Focus on safe and correct IOCP creation, association, and status retrieval.
  • The WindowsError type should be defined to wrap the windows-rs::core::Error type.
Loading editor...
rust