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

`+

}

`