summaryrefslogtreecommitdiff
path: root/ext/web/timers.rs
diff options
context:
space:
mode:
authorhaturau <135221985+haturatu@users.noreply.github.com>2024-11-20 01:20:47 +0900
committerGitHub <noreply@github.com>2024-11-20 01:20:47 +0900
commit85719a67e59c7aa45bead26e4942d7df8b1b42d4 (patch)
treeface0aecaac53e93ce2f23b53c48859bcf1a36ec /ext/web/timers.rs
parent67697bc2e4a62a9670699fd18ad0dd8efc5bd955 (diff)
parent186b52731c6bb326c4d32905c5e732d082e83465 (diff)
Merge branch 'denoland:main' into main
Diffstat (limited to 'ext/web/timers.rs')
-rw-r--r--ext/web/timers.rs65
1 files changed, 47 insertions, 18 deletions
diff --git a/ext/web/timers.rs b/ext/web/timers.rs
index a9ab7c97e..06444ed34 100644
--- a/ext/web/timers.rs
+++ b/ext/web/timers.rs
@@ -4,7 +4,10 @@
use deno_core::op2;
use deno_core::OpState;
+use std::time::Duration;
use std::time::Instant;
+use std::time::SystemTime;
+use std::time::UNIX_EPOCH;
pub trait TimersPermission {
fn allow_hrtime(&mut self) -> bool;
@@ -17,21 +20,28 @@ impl TimersPermission for deno_permissions::PermissionsContainer {
}
}
-pub type StartTime = Instant;
+pub struct StartTime(Instant);
-// Returns a milliseconds and nanoseconds subsec
-// since the start time of the deno runtime.
-// If the High precision flag is not set, the
-// nanoseconds are rounded on 2ms.
-#[op2(fast)]
-pub fn op_now<TP>(state: &mut OpState, #[buffer] buf: &mut [u8])
+impl Default for StartTime {
+ fn default() -> Self {
+ Self(Instant::now())
+ }
+}
+
+impl std::ops::Deref for StartTime {
+ type Target = Instant;
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+fn expose_time<TP>(state: &mut OpState, duration: Duration, out: &mut [u8])
where
TP: TimersPermission + 'static,
{
- let start_time = state.borrow::<StartTime>();
- let elapsed = start_time.elapsed();
- let seconds = elapsed.as_secs();
- let mut subsec_nanos = elapsed.subsec_nanos();
+ let seconds = duration.as_secs() as u32;
+ let mut subsec_nanos = duration.subsec_nanos();
// If the permission is not enabled
// Round the nano result on 2 milliseconds
@@ -40,14 +50,33 @@ where
let reduced_time_precision = 2_000_000; // 2ms in nanoseconds
subsec_nanos -= subsec_nanos % reduced_time_precision;
}
- if buf.len() < 8 {
- return;
+
+ if out.len() >= 8 {
+ out[0..4].copy_from_slice(&seconds.to_ne_bytes());
+ out[4..8].copy_from_slice(&subsec_nanos.to_ne_bytes());
}
- let buf: &mut [u32] =
- // SAFETY: buffer is at least 8 bytes long.
- unsafe { std::slice::from_raw_parts_mut(buf.as_mut_ptr() as _, 2) };
- buf[0] = seconds as u32;
- buf[1] = subsec_nanos;
+}
+
+#[op2(fast)]
+pub fn op_now<TP>(state: &mut OpState, #[buffer] buf: &mut [u8])
+where
+ TP: TimersPermission + 'static,
+{
+ let start_time = state.borrow::<StartTime>();
+ let elapsed = start_time.elapsed();
+ expose_time::<TP>(state, elapsed, buf);
+}
+
+#[op2(fast)]
+pub fn op_time_origin<TP>(state: &mut OpState, #[buffer] buf: &mut [u8])
+where
+ TP: TimersPermission + 'static,
+{
+ // https://w3c.github.io/hr-time/#dfn-estimated-monotonic-time-of-the-unix-epoch
+ let wall_time = SystemTime::now();
+ let monotonic_time = state.borrow::<StartTime>().elapsed();
+ let epoch = wall_time.duration_since(UNIX_EPOCH).unwrap() - monotonic_time;
+ expose_time::<TP>(state, epoch, buf);
}
#[allow(clippy::unused_async)]