Skip to content

Commit 86af86f

Browse files
authored
Merge pull request #338 from wprzytula/session-free-waits-for-close
`cass_session_free` waits for session close
2 parents b6b7e33 + a2ff834 commit 86af86f

File tree

2 files changed

+35
-23
lines changed

2 files changed

+35
-23
lines changed

scylla-rust-wrapper/src/future.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ impl CassFuture {
314314
CassError::CASS_OK
315315
}
316316

317-
fn into_raw(self: Arc<Self>) -> CassOwnedSharedPtr<Self, CMut> {
317+
pub(crate) fn into_raw(self: Arc<Self>) -> CassOwnedSharedPtr<Self, CMut> {
318318
ArcFFI::into_ptr(self)
319319
}
320320

scylla-rust-wrapper/src/session.rs

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ impl CassSessionInner {
105105
}
106106

107107
async fn connect_fut(
108-
session_opt: Arc<RwLock<Option<CassSessionInner>>>,
108+
session_opt: Arc<RwLock<Option<Self>>>,
109109
session_builder_fut: impl Future<Output = SessionBuilder>,
110110
exec_profile_builder_map: HashMap<ExecProfileName, CassExecProfile>,
111111
host_filter: Arc<dyn HostFilter>,
@@ -163,6 +163,26 @@ impl CassSessionInner {
163163
});
164164
Ok(CassResultValue::Empty)
165165
}
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+
}
166186
}
167187

168188
pub type CassSession = RwLock<Option<CassSessionInner>>;
@@ -352,13 +372,12 @@ pub unsafe extern "C" fn cass_session_execute(
352372

353373
let future = async move {
354374
let session_guard = session_opt.read().await;
355-
if session_guard.is_none() {
375+
let Some(cass_session_inner) = session_guard.as_ref() else {
356376
return Err((
357377
CassError::CASS_ERROR_LIB_NO_HOSTS_AVAILABLE,
358378
"Session is not connected".msg(),
359379
));
360-
}
361-
let cass_session_inner = session_guard.as_ref().unwrap();
380+
};
362381
let session = &cass_session_inner.session;
363382

364383
let handle = cass_session_inner
@@ -576,7 +595,16 @@ pub unsafe extern "C" fn cass_session_prepare_n(
576595

577596
#[unsafe(no_mangle)]
578597
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.
580608
}
581609

582610
#[unsafe(no_mangle)]
@@ -588,23 +616,7 @@ pub unsafe extern "C" fn cass_session_close(
588616
return ArcFFI::null();
589617
};
590618

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()
608620
}
609621

610622
#[unsafe(no_mangle)]

0 commit comments

Comments
 (0)