mirror of
https://github.com/denoland/deno.git
synced 2025-08-04 19:08:15 +00:00
feat(ext/web): Request higher-resolution timer on Windows if user requests setTimeout w/short delay (#19149)
If a timer is requested with <=100ms resolution, request the high-res timer. Since the default Windows timer period is 15ms, this means a 100ms timer could fire at 115ms (15% late). We assume that timers longer than 100ms are a reasonable cutoff here. The high-res timers on Windows are still limited. Unfortuntely this means that our shortest duration 4ms timers can still be 25% late, but without a more complex timer system or spinning on the clock itself, we're somewhat bounded by the OS' scheduler itself.
This commit is contained in:
parent
1541c2ac9b
commit
ad22336245
6 changed files with 88 additions and 1 deletions
|
@ -2,9 +2,9 @@
|
|||
|
||||
//! This module helps deno implement timers and performance APIs.
|
||||
|
||||
use crate::hr_timer_lock::hr_timer_lock;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::op;
|
||||
|
||||
use deno_core::CancelFuture;
|
||||
use deno_core::CancelHandle;
|
||||
use deno_core::OpState;
|
||||
|
@ -86,8 +86,24 @@ pub async fn op_sleep(
|
|||
rid: ResourceId,
|
||||
) -> Result<bool, AnyError> {
|
||||
let handle = state.borrow().resource_table.get::<TimerHandle>(rid)?;
|
||||
|
||||
// If a timer is requested with <=100ms resolution, request the high-res timer. Since the default
|
||||
// Windows timer period is 15ms, this means a 100ms timer could fire at 115ms (15% late). We assume that
|
||||
// timers longer than 100ms are a reasonable cutoff here.
|
||||
|
||||
// The high-res timers on Windows are still limited. Unfortuntely this means that our shortest duration 4ms timers
|
||||
// can still be 25% late, but without a more complex timer system or spinning on the clock itself, we're somewhat
|
||||
// bounded by the OS' scheduler itself.
|
||||
let _hr_timer_lock = if millis <= 100 {
|
||||
Some(hr_timer_lock())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let res = tokio::time::sleep(Duration::from_millis(millis))
|
||||
.or_cancel(handle.0.clone())
|
||||
.await;
|
||||
|
||||
// We release the high-res timer lock here, either by being cancelled or resolving.
|
||||
Ok(res.is_ok())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue