Skip to content

Commit 81f7908

Browse files
committed
uefi: Add OwnedEvent abstraction
- Events are going to become quite important for Networking, so needed owned abstractions. - Switch to OwnedEvent abstraction for Exit boot services event. Signed-off-by: Ayush Singh <[email protected]>
1 parent 79b43df commit 81f7908

File tree

2 files changed

+56
-38
lines changed

2 files changed

+56
-38
lines changed

library/std/src/sys/pal/uefi/helpers.rs

+51-33
Original file line numberDiff line numberDiff line change
@@ -120,39 +120,6 @@ pub(crate) fn open_protocol<T>(
120120
}
121121
}
122122

123-
pub(crate) fn create_event(
124-
signal: u32,
125-
tpl: efi::Tpl,
126-
handler: Option<efi::EventNotify>,
127-
context: *mut crate::ffi::c_void,
128-
) -> io::Result<NonNull<crate::ffi::c_void>> {
129-
let boot_services: NonNull<efi::BootServices> =
130-
boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast();
131-
let mut event: r_efi::efi::Event = crate::ptr::null_mut();
132-
let r = unsafe {
133-
let create_event = (*boot_services.as_ptr()).create_event;
134-
(create_event)(signal, tpl, handler, context, &mut event)
135-
};
136-
if r.is_error() {
137-
Err(crate::io::Error::from_raw_os_error(r.as_usize()))
138-
} else {
139-
NonNull::new(event).ok_or(const_error!(io::ErrorKind::Other, "null protocol"))
140-
}
141-
}
142-
143-
/// # SAFETY
144-
/// - The supplied event must be valid
145-
pub(crate) unsafe fn close_event(evt: NonNull<crate::ffi::c_void>) -> io::Result<()> {
146-
let boot_services: NonNull<efi::BootServices> =
147-
boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast();
148-
let r = unsafe {
149-
let close_event = (*boot_services.as_ptr()).close_event;
150-
(close_event)(evt.as_ptr())
151-
};
152-
153-
if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) }
154-
}
155-
156123
/// Gets the Protocol for current system handle.
157124
///
158125
/// Note: Some protocols need to be manually freed. It is the caller's responsibility to do so.
@@ -559,3 +526,54 @@ impl Drop for ServiceProtocol {
559526
}
560527
}
561528
}
529+
530+
#[repr(transparent)]
531+
pub(crate) struct OwnedEvent(NonNull<crate::ffi::c_void>);
532+
533+
impl OwnedEvent {
534+
pub(crate) fn new(
535+
signal: u32,
536+
tpl: efi::Tpl,
537+
handler: Option<efi::EventNotify>,
538+
context: Option<NonNull<crate::ffi::c_void>>,
539+
) -> io::Result<Self> {
540+
let boot_services: NonNull<efi::BootServices> =
541+
boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast();
542+
let mut event: r_efi::efi::Event = crate::ptr::null_mut();
543+
let r = unsafe {
544+
let create_event = (*boot_services.as_ptr()).create_event;
545+
(create_event)(signal, tpl, handler, crate::mem::transmute(context), &mut event)
546+
};
547+
548+
if r.is_error() {
549+
Err(crate::io::Error::from_raw_os_error(r.as_usize()))
550+
} else {
551+
NonNull::new(event)
552+
.ok_or(const_error!(io::ErrorKind::Other, "failed to create event"))
553+
.map(Self)
554+
}
555+
}
556+
557+
pub(crate) fn into_raw(self) -> *mut crate::ffi::c_void {
558+
let r = self.0.as_ptr();
559+
crate::mem::forget(self);
560+
r
561+
}
562+
563+
/// SAFETY: Assumes that ptr is a non-null valid UEFI event
564+
pub(crate) unsafe fn from_raw(ptr: *mut crate::ffi::c_void) -> Self {
565+
Self(unsafe { NonNull::new_unchecked(ptr) })
566+
}
567+
}
568+
569+
impl Drop for OwnedEvent {
570+
fn drop(&mut self) {
571+
if let Some(boot_services) = boot_services() {
572+
let bt: NonNull<r_efi::efi::BootServices> = boot_services.cast();
573+
unsafe {
574+
let close_event = (*bt.as_ptr()).close_event;
575+
(close_event)(self.0.as_ptr())
576+
};
577+
}
578+
}
579+
}

library/std/src/sys/pal/uefi/mod.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,17 @@ pub(crate) unsafe fn init(argc: isize, argv: *const *const u8, _sigpipe: u8) {
4949
unsafe { uefi::env::init_globals(image_handle, system_table) };
5050

5151
// Register exit boot services handler
52-
match helpers::create_event(
52+
match helpers::OwnedEvent::new(
5353
r_efi::efi::EVT_SIGNAL_EXIT_BOOT_SERVICES,
5454
r_efi::efi::TPL_NOTIFY,
5555
Some(exit_boot_service_handler),
56-
crate::ptr::null_mut(),
56+
None,
5757
) {
5858
Ok(x) => {
5959
if EXIT_BOOT_SERVICE_EVENT
6060
.compare_exchange(
6161
crate::ptr::null_mut(),
62-
x.as_ptr(),
62+
x.into_raw(),
6363
Ordering::Release,
6464
Ordering::Acquire,
6565
)
@@ -79,7 +79,7 @@ pub unsafe fn cleanup() {
7979
if let Some(exit_boot_service_event) =
8080
NonNull::new(EXIT_BOOT_SERVICE_EVENT.swap(crate::ptr::null_mut(), Ordering::Acquire))
8181
{
82-
let _ = unsafe { helpers::close_event(exit_boot_service_event) };
82+
let _ = unsafe { helpers::OwnedEvent::from_raw(exit_boot_service_event.as_ptr()) };
8383
}
8484
}
8585

@@ -145,7 +145,7 @@ pub fn abort_internal() -> ! {
145145
if let Some(exit_boot_service_event) =
146146
NonNull::new(EXIT_BOOT_SERVICE_EVENT.load(Ordering::Acquire))
147147
{
148-
let _ = unsafe { helpers::close_event(exit_boot_service_event) };
148+
let _ = unsafe { helpers::OwnedEvent::from_raw(exit_boot_service_event.as_ptr()) };
149149
}
150150

151151
if let (Some(boot_services), Some(handle)) =

0 commit comments

Comments
 (0)