Sha256: 08571bce8a99dd6296ba7099c1f6da8c832d13a8c43db22044c683470147d7d4
Contents?: true
Size: 1.35 KB
Versions: 39
Compression:
Stored size: 1.35 KB
Contents
use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; /// Converts a function to a future that completes on poll. pub(crate) struct BlockingTask<T> { func: Option<T>, } impl<T> BlockingTask<T> { /// Initializes a new blocking task from the given function. pub(crate) fn new(func: T) -> BlockingTask<T> { BlockingTask { func: Some(func) } } } // The closure `F` is never pinned impl<T> Unpin for BlockingTask<T> {} impl<T, R> Future for BlockingTask<T> where T: FnOnce() -> R + Send + 'static, R: Send + 'static, { type Output = R; fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<R> { let me = &mut *self; let func = me .func .take() .expect("[internal exception] blocking task ran twice."); // This is a little subtle: // For convenience, we'd like _every_ call tokio ever makes to Task::poll() to be budgeted // using coop. However, the way things are currently modeled, even running a blocking task // currently goes through Task::poll(), and so is subject to budgeting. That isn't really // what we want; a blocking task may itself want to run tasks (it might be a Worker!), so // we want it to start without any budgeting. crate::runtime::coop::stop(); Poll::Ready(func()) } }
Version data entries
39 entries across 39 versions & 1 rubygems