From 9c89884345e1c4e12e79a347b93e066666996f1b Mon Sep 17 00:00:00 2001 From: Riccardo Zaglia Date: Mon, 19 Jul 2021 17:00:49 +0200 Subject: [PATCH] Support drop guard for session --- openxr/src/instance.rs | 21 ++++++++++++++++++++- openxr/src/session.rs | 10 +++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/openxr/src/instance.rs b/openxr/src/instance.rs index a7831c4c..3fe34df8 100644 --- a/openxr/src/instance.rs +++ b/openxr/src/instance.rs @@ -368,7 +368,26 @@ impl Instance { info: &G::SessionCreateInfo, ) -> Result<(Session, FrameWaiter, FrameStream)> { let handle = G::create_session(self, system, info)?; - Ok(Session::from_raw(self.clone(), handle)) + Ok(Session::from_raw(self.clone(), handle, Box::new(()))) + } + + /// Refer to [`Instance::create_session()`]. The extra `drop_guard` argument is dropped after + /// the session is destroyed and this can be used to ensure safety. + /// + /// # Safety + /// + /// The requirements documented by the graphics API extension must be respected. Among other + /// requirements, `info` must contain valid handles, and certain operations must be externally + /// synchronized. + #[inline] + pub unsafe fn create_session_with_guard( + &self, + system: SystemId, + info: &G::SessionCreateInfo, + drop_guard: DropGuard, + ) -> Result<(Session, FrameWaiter, FrameStream)> { + let handle = G::create_session(self, system, info)?; + Ok(Session::from_raw(self.clone(), handle, drop_guard)) } /// Get the next event, if available diff --git a/openxr/src/session.rs b/openxr/src/session.rs index 1b48e74a..e226d2f3 100644 --- a/openxr/src/session.rs +++ b/openxr/src/session.rs @@ -3,6 +3,8 @@ use std::{marker::PhantomData, ptr, sync::Arc}; use crate::*; +pub(crate) type DropGuard = Box; + /// A rendering session using a particular graphics API `G` /// /// Convertible into an API-agnostic session using [`Session::into_any_graphics`]. @@ -382,9 +384,14 @@ impl Session { pub unsafe fn from_raw( instance: Instance, handle: sys::Session, + drop_guard: DropGuard, ) -> (Self, FrameWaiter, FrameStream) { let session = Self { - inner: Arc::new(SessionInner { instance, handle }), + inner: Arc::new(SessionInner { + instance, + handle, + _drop_guard: drop_guard, + }), _marker: PhantomData, }; ( @@ -448,6 +455,7 @@ impl Clone for Session { pub(crate) struct SessionInner { pub(crate) instance: Instance, pub(crate) handle: sys::Session, + pub(crate) _drop_guard: DropGuard, } impl Drop for SessionInner {