Allow to disable clocks in WasiCtx (#6007)
Takes the approach described in #6004, but also creates a wrapper for the monotonic time that encapsulates the `creation_time` field as well, since they logically belong and are always used together. This makes it easier to configure `WasiCtx` with custom clocks as well as disable them for security or determinism reasons. Closes #6004.
This commit is contained in:
@@ -959,25 +959,22 @@ impl wasi_unstable::WasiUnstable for WasiCtx {
|
||||
match sub.u {
|
||||
types::SubscriptionU::Clock(clocksub) => match clocksub.id {
|
||||
types::Clockid::Monotonic => {
|
||||
let clock = self.clocks.monotonic.deref();
|
||||
let clock = self.clocks.monotonic()?;
|
||||
let precision = Duration::from_nanos(clocksub.precision);
|
||||
let duration = Duration::from_nanos(clocksub.timeout);
|
||||
let deadline = if clocksub
|
||||
let start = if clocksub
|
||||
.flags
|
||||
.contains(types::Subclockflags::SUBSCRIPTION_CLOCK_ABSTIME)
|
||||
{
|
||||
self.clocks
|
||||
.creation_time
|
||||
.checked_add(duration)
|
||||
.ok_or_else(|| Error::overflow().context("deadline"))?
|
||||
clock.creation_time
|
||||
} else {
|
||||
clock
|
||||
.now(precision)
|
||||
.checked_add(duration)
|
||||
.ok_or_else(|| Error::overflow().context("deadline"))?
|
||||
clock.abs_clock.now(precision)
|
||||
};
|
||||
let deadline = start
|
||||
.checked_add(duration)
|
||||
.ok_or_else(|| Error::overflow().context("deadline"))?;
|
||||
poll.subscribe_monotonic_clock(
|
||||
clock,
|
||||
&*clock.abs_clock,
|
||||
deadline,
|
||||
precision,
|
||||
sub.userdata.into(),
|
||||
|
||||
@@ -68,8 +68,8 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
||||
|
||||
async fn clock_res_get(&mut self, id: types::Clockid) -> Result<types::Timestamp, Error> {
|
||||
let resolution = match id {
|
||||
types::Clockid::Realtime => Ok(self.clocks.system.resolution()),
|
||||
types::Clockid::Monotonic => Ok(self.clocks.monotonic.resolution()),
|
||||
types::Clockid::Realtime => Ok(self.clocks.system()?.resolution()),
|
||||
types::Clockid::Monotonic => Ok(self.clocks.monotonic()?.abs_clock.resolution()),
|
||||
types::Clockid::ProcessCputimeId | types::Clockid::ThreadCputimeId => {
|
||||
Err(Error::badf().context("process and thread clocks are not supported"))
|
||||
}
|
||||
@@ -85,7 +85,7 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
||||
let precision = Duration::from_nanos(precision);
|
||||
match id {
|
||||
types::Clockid::Realtime => {
|
||||
let now = self.clocks.system.now(precision).into_std();
|
||||
let now = self.clocks.system()?.now(precision).into_std();
|
||||
let d = now
|
||||
.duration_since(std::time::SystemTime::UNIX_EPOCH)
|
||||
.map_err(|_| {
|
||||
@@ -94,8 +94,9 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
||||
Ok(d.as_nanos().try_into()?)
|
||||
}
|
||||
types::Clockid::Monotonic => {
|
||||
let now = self.clocks.monotonic.now(precision);
|
||||
let d = now.duration_since(self.clocks.creation_time);
|
||||
let clock = self.clocks.monotonic()?;
|
||||
let now = clock.abs_clock.now(precision);
|
||||
let d = now.duration_since(clock.creation_time);
|
||||
Ok(d.as_nanos().try_into()?)
|
||||
}
|
||||
types::Clockid::ProcessCputimeId | types::Clockid::ThreadCputimeId => {
|
||||
@@ -909,25 +910,22 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
||||
match sub.u {
|
||||
types::SubscriptionU::Clock(clocksub) => match clocksub.id {
|
||||
types::Clockid::Monotonic => {
|
||||
let clock = self.clocks.monotonic.deref();
|
||||
let clock = self.clocks.monotonic()?;
|
||||
let precision = Duration::from_nanos(clocksub.precision);
|
||||
let duration = Duration::from_nanos(clocksub.timeout);
|
||||
let deadline = if clocksub
|
||||
let start = if clocksub
|
||||
.flags
|
||||
.contains(types::Subclockflags::SUBSCRIPTION_CLOCK_ABSTIME)
|
||||
{
|
||||
self.clocks
|
||||
.creation_time
|
||||
.checked_add(duration)
|
||||
.ok_or_else(|| Error::overflow().context("deadline"))?
|
||||
clock.creation_time
|
||||
} else {
|
||||
clock
|
||||
.now(precision)
|
||||
.checked_add(duration)
|
||||
.ok_or_else(|| Error::overflow().context("deadline"))?
|
||||
clock.abs_clock.now(precision)
|
||||
};
|
||||
let deadline = start
|
||||
.checked_add(duration)
|
||||
.ok_or_else(|| Error::overflow().context("deadline"))?;
|
||||
poll.subscribe_monotonic_clock(
|
||||
clock,
|
||||
&*clock.abs_clock,
|
||||
deadline,
|
||||
precision,
|
||||
sub.userdata.into(),
|
||||
@@ -939,7 +937,7 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
||||
// on threads waiting in these functions. MONOTONIC should always have
|
||||
// resolution at least as good as REALTIME, so we can translate a
|
||||
// non-absolute `REALTIME` request into a `MONOTONIC` request.
|
||||
let clock = self.clocks.monotonic.deref();
|
||||
let clock = self.clocks.monotonic()?;
|
||||
let precision = Duration::from_nanos(clocksub.precision);
|
||||
let duration = Duration::from_nanos(clocksub.timeout);
|
||||
let deadline = if clocksub
|
||||
@@ -949,12 +947,13 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
|
||||
return Err(Error::not_supported());
|
||||
} else {
|
||||
clock
|
||||
.abs_clock
|
||||
.now(precision)
|
||||
.checked_add(duration)
|
||||
.ok_or_else(|| Error::overflow().context("deadline"))?
|
||||
};
|
||||
poll.subscribe_monotonic_clock(
|
||||
clock,
|
||||
&*clock.abs_clock,
|
||||
deadline,
|
||||
precision,
|
||||
sub.userdata.into(),
|
||||
|
||||
Reference in New Issue
Block a user