Skip to content

Commit 801d838

Browse files
authored
Simplify the timers API (#507)
1 parent 900bc63 commit 801d838

File tree

5 files changed

+24
-30
lines changed

5 files changed

+24
-30
lines changed

wasm-node/javascript/src/instance/bindings-smoldot-light.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ export default function (config: Config): { imports: WebAssembly.ModuleImports,
308308
},
309309

310310
// Must call `timer_finished` after the given number of milliseconds has elapsed.
311-
start_timer: (id: number, ms: number) => {
311+
start_timer: (ms: number) => {
312312
if (killedTracked.killed) return;
313313

314314
const instance = config.instance!;
@@ -327,14 +327,14 @@ export default function (config: Config): { imports: WebAssembly.ModuleImports,
327327
setImmediate(() => {
328328
if (killedTracked.killed) return;
329329
try {
330-
instance.exports.timer_finished(id);
330+
instance.exports.timer_finished();
331331
} catch (_error) { }
332332
})
333333
} else {
334334
setTimeout(() => {
335335
if (killedTracked.killed) return;
336336
try {
337-
instance.exports.timer_finished(id);
337+
instance.exports.timer_finished();
338338
} catch (_error) { }
339339
}, ms)
340340
}

wasm-node/javascript/src/instance/bindings.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export interface SmoldotWasmExports extends WebAssembly.Exports {
3434
json_rpc_send: (textBufferIndex: number, chainId: number) => number,
3535
json_rpc_responses_peek: (chainId: number) => number,
3636
json_rpc_responses_pop: (chainId: number) => void,
37-
timer_finished: (timerId: number) => void,
37+
timer_finished: () => void,
3838
connection_open_single_stream: (connectionId: number, handshakeTy: number, initialWritableBytes: number, writeClosable: number) => void,
3939
connection_open_multi_stream: (connectionId: number, handshakeTyBufferIndex: number) => void,
4040
stream_writable_bytes: (connectionId: number, streamId: number, numBytes: number) => void,

wasm-node/rust/src/bindings.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,7 @@ extern "C" {
134134
/// [`advance_execution`] should be called again immediately after it returns.
135135
pub fn advance_execution_ready();
136136

137-
/// After at least `milliseconds` milliseconds have passed, must call [`timer_finished`] with
138-
/// the `id` passed as parameter.
137+
/// After at least `milliseconds` milliseconds have passed, [`timer_finished`] must be called.
139138
///
140139
/// It is not a logic error to call [`timer_finished`] *before* `milliseconds` milliseconds
141140
/// have passed, and this will likely cause smoldot to restart a new timer for the remainder
@@ -147,7 +146,7 @@ extern "C" {
147146
/// If `milliseconds` is 0, [`timer_finished`] should be called as soon as possible.
148147
///
149148
/// `milliseconds` never contains a negative number, `NaN` or infinite.
150-
pub fn start_timer(id: u32, milliseconds: f64);
149+
pub fn start_timer(milliseconds: f64);
151150

152151
/// Must initialize a new connection that tries to connect to the given multiaddress.
153152
///
@@ -481,8 +480,8 @@ pub extern "C" fn json_rpc_responses_pop(chain_id: u32) {
481480

482481
/// Must be called in response to [`start_timer`] after the given duration has passed.
483482
#[no_mangle]
484-
pub extern "C" fn timer_finished(timer_id: u32) {
485-
crate::timers::timer_finished(timer_id);
483+
pub extern "C" fn timer_finished() {
484+
crate::timers::timer_finished();
486485
}
487486

488487
/// Called by the JavaScript code if the connection switches to the `Open` state. The connection

wasm-node/rust/src/lib.rs

+1-11
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#![deny(rustdoc::broken_intra_doc_links)]
2121
#![deny(unused_crate_dependencies)]
2222

23-
use core::{future, mem, num::NonZeroU32, pin::Pin, str, time::Duration};
23+
use core::{future, mem, num::NonZeroU32, pin::Pin, str};
2424
use futures_util::{stream, Stream as _, StreamExt as _};
2525
use smoldot_light::HandleRpcError;
2626
use std::{
@@ -35,16 +35,6 @@ mod init;
3535
mod platform;
3636
mod timers;
3737

38-
/// Uses the environment to invoke `closure` after at least `duration` has elapsed.
39-
fn start_timer_wrap(duration: Duration, closure: impl FnOnce() + 'static) {
40-
let callback: Box<Box<dyn FnOnce() + 'static>> = Box::new(Box::new(closure));
41-
let timer_id = u32::try_from(Box::into_raw(callback) as usize).unwrap();
42-
// Note that ideally `duration` should be rounded up in order to make sure that it is not
43-
// truncated, but the precision of an `f64` is so high and the precision of the operating
44-
// system generally so low that this is not worth dealing with.
45-
unsafe { bindings::start_timer(timer_id, duration.as_secs_f64() * 1000.0) }
46-
}
47-
4838
static CLIENT: Mutex<Option<init::Client<platform::Platform, ()>>> = Mutex::new(None);
4939

5040
fn init(max_log_level: u32, enable_current_task: u32) {

wasm-node/rust/src/timers.rs

+15-10
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
//! is only used in order to wake up when the earliest timer finishes, then restarted for the next
2323
//! timer.
2424
25+
use crate::bindings;
26+
2527
use core::{
2628
cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd},
2729
future,
@@ -31,13 +33,8 @@ use core::{
3133
};
3234
use std::{collections::BinaryHeap, sync::Mutex, time::Instant};
3335

34-
pub(crate) fn timer_finished(timer_id: u32) {
35-
let callback = {
36-
let ptr = timer_id as *mut Box<dyn FnOnce() + 'static>;
37-
unsafe { Box::from_raw(ptr) }
38-
};
39-
40-
callback();
36+
pub(crate) fn timer_finished() {
37+
process_timers();
4138
}
4239

4340
/// `Future` that automatically wakes up after a certain amount of time has elapsed.
@@ -81,9 +78,9 @@ impl Delay {
8178
// If the timer that has just been inserted is the one that ends the soonest, then
8279
// actually start the callback that will process timers.
8380
// Ideally we would instead cancel or update the deadline of the previous call to
84-
// `start_timer_wrap`, but this isn't possible.
81+
// `start_timer`, but this isn't possible.
8582
if lock.timers_queue.peek().unwrap().timer_id == timer_id {
86-
super::start_timer_wrap(when - now, process_timers);
83+
start_timer(when - now);
8784
}
8885

8986
Delay {
@@ -245,10 +242,18 @@ fn process_timers() {
245242
};
246243

247244
if let Some(next_wakeup) = next_wakeup {
248-
super::start_timer_wrap(lock.time_zero + next_wakeup - now, process_timers);
245+
start_timer(lock.time_zero + next_wakeup - now);
249246
} else {
250247
// Clean up memory a bit. Hopefully this doesn't impact performances too much.
251248
lock.timers_queue.shrink_to_fit();
252249
lock.timers.shrink_to_fit();
253250
}
254251
}
252+
253+
/// Instructs the environment to call [`process_timers`] after the given duration.
254+
fn start_timer(duration: Duration) {
255+
// Note that ideally `duration` should be rounded up in order to make sure that it is not
256+
// truncated, but the precision of an `f64` is so high and the precision of the operating
257+
// system generally so low that this is not worth dealing with.
258+
unsafe { bindings::start_timer(duration.as_secs_f64() * 1000.0) }
259+
}

0 commit comments

Comments
 (0)