Hone logo
Hone
Problems

Implementing a Simple Waker System in Rust

This challenge asks you to implement a basic waker system in Rust, mimicking the core functionality of the Waker type used in asynchronous programming. Understanding how wakers work is crucial for grasping the inner workings of Rust's async/await system and building custom asynchronous primitives. You'll be creating a simplified version that allows you to "wake up" a task.

Problem Description

You need to implement a Waker struct and its associated wake method. The Waker should internally hold a closure that, when called, signals that a task should be resumed. The wake method should execute this closure. This is a simplified model; in reality, wakers interact with the runtime to schedule tasks, but here we'll focus on the core signaling mechanism.

Key Requirements:

  • Waker Struct: Define a Waker struct that encapsulates a closure.
  • wake Method: Implement a wake method on the Waker struct. This method should execute the closure stored within the Waker.
  • Closure Capture: The closure should capture at least one piece of data (e.g., an integer) to demonstrate that closures can be used to store state.
  • No Runtime Dependency: The solution should not depend on any external asynchronous runtime libraries (e.g., tokio, async-std). This is a standalone implementation.

Expected Behavior:

When wake is called on a Waker instance, the closure it holds should be executed. The closure's execution should have a visible side effect (e.g., printing a message, incrementing a counter).

Edge Cases to Consider:

  • What happens if wake is called multiple times? (The closure should execute each time.)
  • How can you ensure the closure is not executed prematurely? (This is a simplified system, so we're not focusing on complex synchronization, but consider the implications.)

Examples

Example 1:

Input:
```rust
let captured_value = 42;
let waker = Waker::new(move || {
    println!("Waker triggered! Captured value: {}", captured_value);
});
waker.wake();
waker.wake();

Output:

Waker triggered! Captured value: 42
Waker triggered! Captured value: 42

Explanation: The Waker is created with a closure that prints a message including the captured value. Calling wake() twice executes the closure twice, resulting in the message being printed twice.

Example 2:

Input:
```rust
let mut counter = 0;
let waker = Waker::new(move || {
    counter += 1;
    println!("Waker triggered! Counter: {}", counter);
});
waker.wake();
waker.wake();

Output:

Waker triggered! Counter: 1
Waker triggered! Counter: 2

Explanation: The closure increments a counter and prints its value. Calling wake() twice increments the counter and prints the updated value each time.

Constraints

  • The solution must be written in Rust.
  • The Waker struct and wake method must be implemented as described.
  • The closure captured by the Waker must capture at least one piece of data.
  • The solution should not use any external asynchronous runtime libraries.
  • The code should be well-formatted and easy to understand.

Notes

  • This is a simplified waker system. Real-world wakers interact with the asynchronous runtime to schedule tasks.
  • Focus on the core concept of signaling a task to be resumed.
  • Consider how the closure's capture list affects its behavior.
  • Think about the implications of calling wake multiple times. While not a primary focus, understanding this behavior is important.
  • The Waker struct itself doesn't need to be thread-safe in this simplified scenario.
Loading editor...
rust