use crate::error::CudaError;
use super::ContextInner;
pub(crate) fn ensure_context_ownership(
matches_context: impl IntoIterator<Item = bool>,
mismatch_message: &'static str,
) -> Result<(), CudaError> {
if matches_context.into_iter().all(|matches| matches) {
Ok(())
} else {
Err(CudaError::InvalidArgument {
message: mismatch_message.to_string(),
})
}
}
impl ContextInner {
pub(crate) fn set_current(&self) -> Result<(), CudaError> {
self.resource_lifecycle.run_recoverable(
|| self.set_current_for_resource_release(),
|| Ok(()),
|| self.synchronize_current_after_operation_error(),
)
}
pub(crate) fn set_current_for_resource_release(&self) -> Result<(), CudaError> {
self.driver.check("cuCtxSetCurrent", unsafe {
(self.driver.cu_ctx_set_current)(self.context)
})
}
pub(crate) fn ensure_resource_lifetime_available(&self) -> Result<(), CudaError> {
self.resource_lifecycle.ensure_available()
}
pub(crate) fn with_current_resource_operation<T>(
&self,
operation: impl FnOnce() -> Result<T, CudaError>,
) -> Result<T, CudaError> {
self.resource_lifecycle.run_recoverable(
|| self.set_current_for_resource_release(),
operation,
|| self.synchronize_current_after_operation_error(),
)
}
pub(crate) fn with_current_completion_operation<T>(
&self,
operation: impl FnOnce() -> Result<T, CudaError>,
) -> Result<T, CudaError> {
self.resource_lifecycle
.run_completion(|| self.set_current_for_resource_release(), operation)
}
pub(crate) fn with_current_stateful_operation<T>(
&self,
operation: impl FnOnce() -> Result<T, CudaError>,
) -> Result<T, CudaError> {
self.resource_lifecycle.run_stateful(
|| self.set_current_for_resource_release(),
operation,
|| self.synchronize_current_after_operation_error(),
)
}
fn synchronize_current_after_operation_error(&self) -> Result<(), CudaError> {
let status = unsafe { (self.driver.cu_ctx_synchronize)() };
self.driver.check("cuCtxSynchronize", status)
}
pub(crate) fn resource_lifetimes_poisoned(&self) -> bool {
self.resource_lifecycle.is_poisoned()
}
}