1- //use super::object::NeonObject;
21use super :: {
32 inner_types:: NeonInnerTypes ,
43 object:: {
@@ -7,12 +6,15 @@ use super::{
76 } ,
87} ;
98use crate :: wrappers:: {
10- context:: NativeContext , object:: NativeObject , object_handle:: NativeObjectHandle ,
9+ context:: { NativeContext , NativeContextHolder } ,
10+ object:: NativeObject ,
11+ object_handle:: NativeObjectHandle ,
1112} ;
1213use cubesql:: CubeError ;
1314use neon:: prelude:: * ;
1415use std:: {
15- cell:: RefCell ,
16+ cell:: { RefCell , RefMut } ,
17+ marker:: PhantomData ,
1618 panic:: { catch_unwind, resume_unwind, AssertUnwindSafe } ,
1719 rc:: { Rc , Weak } ,
1820} ;
@@ -50,18 +52,42 @@ impl<C: Context<'static>> ContextWrapper<C> {
5052 }
5153}
5254
55+ pub struct NeonContextGuard < ' cx , C : Context < ' cx > + NoenContextLifetimeExpand < ' cx > > {
56+ context : Rc < RefCell < ContextWrapper < C :: ExpandedResult > > > ,
57+ lifetime : PhantomData < & ' cx ( ) > ,
58+ }
59+
60+ impl < ' cx , C : Context < ' cx > + NoenContextLifetimeExpand < ' cx > + ' cx > NeonContextGuard < ' cx , C > {
61+ fn new ( cx : C ) -> Self {
62+ Self {
63+ context : ContextWrapper :: new ( cx. expand_lifetime ( ) ) ,
64+ lifetime : PhantomData :: default ( ) ,
65+ }
66+ }
67+
68+ fn context_holder ( & self ) -> ContextHolder < C :: ExpandedResult > {
69+ ContextHolder :: new ( Rc :: downgrade ( & self . context ) )
70+ }
71+
72+ fn unwrap ( self ) {
73+ if Rc :: strong_count ( & self . context ) > 0 {
74+ match Rc :: try_unwrap ( self . context ) {
75+ Ok ( _) => { }
76+ Err ( _) => panic ! ( "Guarded context have more then one reference" ) ,
77+ }
78+ }
79+ }
80+ }
81+
5382pub fn neon_run_with_guarded_lifetime < ' cx , C , T , F > ( cx : C , func : F ) -> T
5483where
55- C : Context < ' cx > + NoenContextLifetimeExpand < ' cx > ,
84+ C : Context < ' cx > + NoenContextLifetimeExpand < ' cx > + ' cx ,
5685 F : FnOnce ( ContextHolder < C :: ExpandedResult > ) -> T ,
5786{
58- let context = ContextWrapper :: new ( cx. expand_lifetime ( ) ) ;
59- let context_holder = ContextHolder :: new ( Rc :: downgrade ( & context ) ) ;
87+ let guard = NeonContextGuard :: new ( cx) ;
88+ let context_holder = guard . context_holder ( ) ;
6089 let res = catch_unwind ( AssertUnwindSafe ( || func ( context_holder) ) ) ;
61- match Rc :: try_unwrap ( context) {
62- Ok ( _) => { }
63- Err ( _) => panic ! ( "Guarded context have more then one reference" ) ,
64- } ;
90+ guard. unwrap ( ) ;
6591
6692 match res {
6793 Ok ( res) => res,
0 commit comments