uefi: Add OwnedEvent abstraction · rust-lang/rust@aa2c24b (original) (raw)
`@@ -120,39 +120,6 @@ pub(crate) fn open_protocol(
`
120
120
`}
`
121
121
`}
`
122
122
``
123
``
`-
pub(crate) fn create_event(
`
124
``
`-
signal: u32,
`
125
``
`-
tpl: efi::Tpl,
`
126
``
`-
handler: Optionefi::EventNotify,
`
127
``
`-
context: *mut crate::ffi::c_void,
`
128
``
`-
) -> io::Result<NonNullcrate::ffi::c_void> {
`
129
``
`-
let boot_services: NonNullefi::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: NonNullcrate::ffi::c_void) -> io::Result<()> {
`
146
``
`-
let boot_services: NonNullefi::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
``
-
156
123
`/// Gets the Protocol for current system handle.
`
157
124
`///
`
158
125
`/// Note: Some protocols need to be manually freed. It is the caller's responsibility to do so.
`
`@@ -559,3 +526,56 @@ impl Drop for ServiceProtocol {
`
559
526
`}
`
560
527
`}
`
561
528
`}
`
``
529
+
``
530
`+
#[repr(transparent)]
`
``
531
`+
pub(crate) struct OwnedEvent(NonNullcrate::ffi::c_void);
`
``
532
+
``
533
`+
impl OwnedEvent {
`
``
534
`+
pub(crate) fn new(
`
``
535
`+
signal: u32,
`
``
536
`+
tpl: efi::Tpl,
`
``
537
`+
handler: Optionefi::EventNotify,
`
``
538
`+
context: Option<NonNullcrate::ffi::c_void>,
`
``
539
`+
) -> io::Result {
`
``
540
`+
let boot_services: NonNullefi::BootServices =
`
``
541
`+
boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast();
`
``
542
`+
let mut event: r_efi::efi::Event = crate::ptr::null_mut();
`
``
543
`+
let context = context.map(NonNull::as_ptr).unwrap_or(crate::ptr::null_mut());
`
``
544
+
``
545
`+
let r = unsafe {
`
``
546
`+
let create_event = (*boot_services.as_ptr()).create_event;
`
``
547
`+
(create_event)(signal, tpl, handler, context, &mut event)
`
``
548
`+
};
`
``
549
+
``
550
`+
if r.is_error() {
`
``
551
`+
Err(crate::io::Error::from_raw_os_error(r.as_usize()))
`
``
552
`+
} else {
`
``
553
`+
NonNull::new(event)
`
``
554
`+
.ok_or(const_error!(io::ErrorKind::Other, "failed to create event"))
`
``
555
`+
.map(Self)
`
``
556
`+
}
`
``
557
`+
}
`
``
558
+
``
559
`+
pub(crate) fn into_raw(self) -> *mut crate::ffi::c_void {
`
``
560
`+
let r = self.0.as_ptr();
`
``
561
`+
crate::mem::forget(self);
`
``
562
`+
r
`
``
563
`+
}
`
``
564
+
``
565
`+
/// SAFETY: Assumes that ptr is a non-null valid UEFI event
`
``
566
`+
pub(crate) unsafe fn from_raw(ptr: *mut crate::ffi::c_void) -> Self {
`
``
567
`+
Self(unsafe { NonNull::new_unchecked(ptr) })
`
``
568
`+
}
`
``
569
`+
}
`
``
570
+
``
571
`+
impl Drop for OwnedEvent {
`
``
572
`+
fn drop(&mut self) {
`
``
573
`+
if let Some(boot_services) = boot_services() {
`
``
574
`+
let bt: NonNull<r_efi::efi::BootServices> = boot_services.cast();
`
``
575
`+
unsafe {
`
``
576
`+
let close_event = (*bt.as_ptr()).close_event;
`
``
577
`+
(close_event)(self.0.as_ptr())
`
``
578
`+
};
`
``
579
`+
}
`
``
580
`+
}
`
``
581
`+
}
`