use crate::sim::WeakSimWorld;
use crate::sim::state::FileId;
use std::cell::Cell;
use std::future::Future;
use std::io;
use std::pin::Pin;
use std::task::{Context, Poll};
use super::sim_shutdown_error;
pub struct SyncFuture {
sim: WeakSimWorld,
file_id: FileId,
pending_op: Cell<Option<u64>>,
}
impl SyncFuture {
pub(crate) fn new(sim: WeakSimWorld, file_id: FileId) -> Self {
Self {
sim,
file_id,
pending_op: Cell::new(None),
}
}
}
impl Future for SyncFuture {
type Output = io::Result<()>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let sim = self.sim.upgrade().map_err(|_| sim_shutdown_error())?;
if let Some(op_seq) = self.pending_op.get() {
if sim.is_storage_op_complete(self.file_id, op_seq) {
self.pending_op.set(None);
if sim.take_sync_failure(self.file_id, op_seq) {
return Poll::Ready(Err(io::Error::other("sync failed (simulated I/O error)")));
}
return Poll::Ready(Ok(()));
}
sim.register_storage_waker(self.file_id, op_seq, cx.waker().clone());
return Poll::Pending;
}
let op_seq = sim.schedule_sync(self.file_id)?;
self.pending_op.set(Some(op_seq));
sim.register_storage_waker(self.file_id, op_seq, cx.waker().clone());
Poll::Pending
}
}
pub struct SetLenFuture {
sim: WeakSimWorld,
file_id: FileId,
new_len: u64,
pending_op: Cell<Option<u64>>,
}
impl SetLenFuture {
pub(crate) fn new(sim: WeakSimWorld, file_id: FileId, new_len: u64) -> Self {
Self {
sim,
file_id,
new_len,
pending_op: Cell::new(None),
}
}
}
impl Future for SetLenFuture {
type Output = io::Result<()>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let sim = self.sim.upgrade().map_err(|_| sim_shutdown_error())?;
if let Some(op_seq) = self.pending_op.get() {
if sim.is_storage_op_complete(self.file_id, op_seq) {
self.pending_op.set(None);
return Poll::Ready(Ok(()));
}
sim.register_storage_waker(self.file_id, op_seq, cx.waker().clone());
return Poll::Pending;
}
let op_seq = sim.schedule_set_len(self.file_id, self.new_len)?;
self.pending_op.set(Some(op_seq));
sim.register_storage_waker(self.file_id, op_seq, cx.waker().clone());
Poll::Pending
}
}