@@ -105,7 +105,7 @@ impl CassSessionInner {
105
105
}
106
106
107
107
async fn connect_fut (
108
- session_opt : Arc < RwLock < Option < CassSessionInner > > > ,
108
+ session_opt : Arc < RwLock < Option < Self > > > ,
109
109
session_builder_fut : impl Future < Output = SessionBuilder > ,
110
110
exec_profile_builder_map : HashMap < ExecProfileName , CassExecProfile > ,
111
111
host_filter : Arc < dyn HostFilter > ,
@@ -163,6 +163,26 @@ impl CassSessionInner {
163
163
} ) ;
164
164
Ok ( CassResultValue :: Empty )
165
165
}
166
+
167
+ fn close_fut ( session_opt : Arc < RwLock < Option < Self > > > ) -> Arc < CassFuture > {
168
+ CassFuture :: new_from_future (
169
+ async move {
170
+ let mut session_guard = session_opt. write ( ) . await ;
171
+ if session_guard. is_none ( ) {
172
+ return Err ( (
173
+ CassError :: CASS_ERROR_LIB_UNABLE_TO_CLOSE ,
174
+ "Already closing or closed" . msg ( ) ,
175
+ ) ) ;
176
+ }
177
+
178
+ * session_guard = None ;
179
+
180
+ Ok ( CassResultValue :: Empty )
181
+ } ,
182
+ #[ cfg( cpp_integration_testing) ]
183
+ None ,
184
+ )
185
+ }
166
186
}
167
187
168
188
pub type CassSession = RwLock < Option < CassSessionInner > > ;
@@ -352,13 +372,12 @@ pub unsafe extern "C" fn cass_session_execute(
352
372
353
373
let future = async move {
354
374
let session_guard = session_opt. read ( ) . await ;
355
- if session_guard. is_none ( ) {
375
+ let Some ( cass_session_inner ) = session_guard. as_ref ( ) else {
356
376
return Err ( (
357
377
CassError :: CASS_ERROR_LIB_NO_HOSTS_AVAILABLE ,
358
378
"Session is not connected" . msg ( ) ,
359
379
) ) ;
360
- }
361
- let cass_session_inner = session_guard. as_ref ( ) . unwrap ( ) ;
380
+ } ;
362
381
let session = & cass_session_inner. session ;
363
382
364
383
let handle = cass_session_inner
@@ -576,7 +595,16 @@ pub unsafe extern "C" fn cass_session_prepare_n(
576
595
577
596
#[ unsafe( no_mangle) ]
578
597
pub unsafe extern "C" fn cass_session_free ( session_raw : CassOwnedSharedPtr < CassSession , CMut > ) {
579
- ArcFFI :: free ( session_raw) ;
598
+ let Some ( session_opt) = ArcFFI :: from_ptr ( session_raw) else {
599
+ // `free()` does nothing on null pointers, so by analogy let's do nothing here.
600
+ return ;
601
+ } ;
602
+
603
+ let close_fut = CassSessionInner :: close_fut ( session_opt) ;
604
+ close_fut. with_waited_result ( |_| ( ) ) ;
605
+
606
+ // We don't have to drop the session's Arc explicitly, because it has been moved
607
+ // into the CassFuture, which is dropped here with the end of the scope.
580
608
}
581
609
582
610
#[ unsafe( no_mangle) ]
@@ -588,23 +616,7 @@ pub unsafe extern "C" fn cass_session_close(
588
616
return ArcFFI :: null ( ) ;
589
617
} ;
590
618
591
- CassFuture :: make_raw (
592
- async move {
593
- let mut session_guard = session_opt. write ( ) . await ;
594
- if session_guard. is_none ( ) {
595
- return Err ( (
596
- CassError :: CASS_ERROR_LIB_UNABLE_TO_CLOSE ,
597
- "Already closing or closed" . msg ( ) ,
598
- ) ) ;
599
- }
600
-
601
- * session_guard = None ;
602
-
603
- Ok ( CassResultValue :: Empty )
604
- } ,
605
- #[ cfg( cpp_integration_testing) ]
606
- None ,
607
- )
619
+ CassSessionInner :: close_fut ( session_opt) . into_raw ( )
608
620
}
609
621
610
622
#[ unsafe( no_mangle) ]
0 commit comments