1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
use std::sync::Arc; use async_std::task; use async_macros::join; use async_std::sync::{ channel }; use crate::base::{ Protocol, Session, Context, AppendContext, PartialSession, unsafe_run_session, unsafe_create_session, }; use crate::functional::nat::*; pub struct PersistentSession < P > where P : Protocol { new_session : Arc < dyn Fn () -> Session < P > + Send + Sync > } impl < P > Clone for PersistentSession < P > where P : Protocol { fn clone(&self) -> Self { PersistentSession { new_session : self.new_session.clone() } } } pub fn create_persistent_session < F, P > (f : F) -> PersistentSession < P > where P : Protocol, F : Fn () -> Session < P > + Send + Sync + 'static { return PersistentSession { new_session: Arc::new ( f ) } } pub fn clone_session < I, P, Q, F > ( session1 : &PersistentSession < P >, cont_builder : F ) -> PartialSession < I, Q > where P : Protocol, Q : Protocol, I : Context, I : AppendContext < ( P, () ) >, F : FnOnce ( I::Length ) -> PartialSession < < I as AppendContext < ( P, () ) > > :: Appended, Q > { let session2 = session1.clone(); let cont = cont_builder ( I::Length::nat() ); unsafe_create_session ( move | ctx1, sender1 | async move { let session3 = (session2.new_session)(); let (sender2, receiver2) = channel(1); let child1 = task::spawn(async move { unsafe_run_session ( session3, (), sender2 ).await; }); let ctx2 = < I as AppendContext < ( P, () ) > > :: append_context ( ctx1, (receiver2, ()) ); let child2 = task::spawn(async move { unsafe_run_session ( cont, ctx2, sender1 ).await; }); join!(child1, child2).await; }) }