This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//! This is an internal implementation of sample API. The | |
//! implementation pretends to make network calls and accesses locked | |
//! data. It is wrapped by a function-based API that operates a | |
//! singleton. | |
use base::{AsyncRwLock, LockBox, Runtime}; | |
use implbox::ImplBox; | |
use std::error::Error; | |
use std::marker::PhantomData; | |
use std::ops::DerefMut; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -ur --ex 04-generic-async-rwlock-first-try/controller/src/lib.rs 05-final/controller/src/lib.rs | |
--- 04-generic-async-rwlock-first-try/controller/src/lib.rs 2024-12-01 16:36:03 | |
+++ 05-final/controller/src/lib.rs 2024-12-01 19:26:01 | |
@@ -2,8 +2,11 @@ | |
//! implementation pretends to make network calls and accesses locked | |
//! data. It is wrapped by a function-based API that operates a | |
//! singleton. | |
-use base::AsyncRwLock; | |
+use base::{AsyncRwLock, LockBox, Runtime}; | |
+use implbox::ImplBox; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::any::TypeId; | |
use std::marker::PhantomData; | |
unsafe impl<T: Send> Send for ImplBox<T> {} | |
unsafe impl<T: Sync> Sync for ImplBox<T> {} | |
pub struct ImplBox<T> { | |
id: TypeId, | |
ptr: *const (), | |
destroy: fn(*const ()), | |
_t: PhantomData<T>, |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use super::*; | |
use crate::{Locker, TokioRuntime}; | |
use std::sync::Arc; | |
use std::time::Duration; | |
use tokio::sync::oneshot; | |
use tokio::task; | |
async fn generic_thing<M>(m: &M) | |
where | |
M: AsyncRwLock<i32>, |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use crate::rwlock::TokioLockWrapper; | |
use base::{AsyncRwLock, Locker, Runtime}; | |
pub mod rwlock; | |
#[derive(Default, Clone)] | |
pub struct TokioRuntime; | |
impl Locker for TokioRuntime { | |
fn new_lock<T: Sync + Send>(item: T) -> impl AsyncRwLock<T> { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::ops::{Deref, DerefMut}; | |
pub trait Runtime: Locker {} | |
/// The [AsyncRwLock::read] and [AsyncRwLock::write] functions must return | |
/// actual async-aware lock guards that maintain the lock until they are out of | |
/// scope. They must not block the thread while holding the lock. | |
pub trait AsyncRwLock<T> { | |
fn new(item: T) -> Self; | |
fn read( |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::error::Error; | |
use tokio::sync::RwLock; | |
#[derive(Default)] | |
struct ReqData { | |
seq: i32, | |
last_path: String, | |
} | |
#[derive(Default)] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trait MethodCaller<'a, ArgT, ResultT>: FnOnce(&'a Controller, ArgT) -> Self::Fut { | |
type Fut: Future<Output = Result<ResultT, Box<dyn Error + Sync + Send>>>; | |
} | |
impl< | |
'a, | |
ArgT, | |
ResultT, | |
FnT: FnOnce(&'a Controller, ArgT) -> Fut, | |
Fut: Future<Output = Result<ResultT, Box<dyn Error + Sync + Send>>>, | |
> MethodCaller<'a, ArgT, ResultT> for FnT |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
error[E0308]: mismatched types | |
--> device/src/lib.rs:51:5 | |
| | |
51 | run_method(Controller::one, val) | |
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other | |
| | |
= note: expected opaque type `impl for<'a> Future<Output = Result<i32, Box<(dyn std::error::Error + Send + Sync + 'static)>>>` | |
found opaque type `impl Future<Output = Result<i32, Box<(dyn std::error::Error + Send + Sync + 'static)>>>` | |
= help: consider `await`ing on both `Future`s | |
= note: distinct uses of `impl Trait` result in different opaque types |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@@ -25,17 +24,15 @@ | |
/// call methods on the singleton. It takes a closure that takes a | |
/// &[Controller] and an arg, calls the closure using the singleton, | |
/// and returns the result. | |
-fn run_method<ArgT, ResultT, FnT>( | |
+fn run_method<ArgT, ResultT, FnT, Fut>( | |
f: FnT, | |
arg: ArgT, | |
) -> Result<ResultT, Box<dyn Error + Sync + Send>> | |
where |
NewerOlder