Skip to main content

CloseRequest

Struct CloseRequest 

Source
pub struct CloseRequest { /* private fields */ }
Expand description

An owned, marshalable request to close one handle.

The request owns the handle it will close, so the handle cannot be closed by anyone else in the meantime, and cannot outlive the request unclosed.

§Example

use std::fs;

use windows_namespace_request_sys::close::CloseRequest;

let path = std::env::temp_dir().join(format!("wnrs-close-{}.tmp", std::process::id()));
fs::write(&path, b"example")?;
let file = fs::File::open(&path)?;

// The close is a value now, so it can be performed wherever blocking is
// acceptable rather than wherever the handle happens to be dropped.
let request = CloseRequest::for_handle(file.into());
request.perform()?;

§Example: the routine travels with the handle

A change notification is closed with FindCloseChangeNotification, and CloseHandle is silently wrong for it. A caller never has to know that, because the constructor pairs them:

use std::fs;

use windows_namespace_request_sys::close::CloseRequest;
use windows_namespace_request_sys::prepare;
use windows_namespace_request_sys::watch::{NotifyFilter, WatchDirectory};
use wtf_string::Wtf16String;

let directory = std::env::temp_dir().join(format!("wnrs-cr-{}", std::process::id()));
let _ = fs::remove_dir_all(&directory);
fs::create_dir_all(&directory)?;
let text = directory.to_str().expect("a temporary path is valid UTF-8");

let notification = WatchDirectory::new(prepare(&Wtf16String::from(text))?)
    .with_filter(NotifyFilter::FILE_NAME)
    .perform()?;

let request = CloseRequest::for_change_notification(notification);
assert!(format!("{request:?}").contains("FindCloseChangeNotification"));
request.perform()?;

§Example: performing consumes the request

This is what makes closing twice through this type impossible – the second call does not compile:

use std::fs;

use windows_namespace_request_sys::close::CloseRequest;

let path = std::env::temp_dir().join("wnrs-doc-double-close.tmp");
fs::write(&path, b"x").unwrap();
let request = CloseRequest::for_handle(fs::File::open(&path).unwrap().into());

request.perform().unwrap();
request.perform().unwrap(); // error: use of moved value

Implementations§

Source§

impl CloseRequest

Source

pub fn for_handle(handle: OwnedHandle) -> Self

A request to close an ordinary handle with CloseHandle.

Source

pub fn for_change_notification(notification: ChangeNotification) -> Self

A request to close a change notification with FindCloseChangeNotification.

Provided by name so a caller never has to know which routine is right: this is precisely the pairing the audit found a close entry cannot assume.

Source

pub unsafe fn from_raw(handle: HANDLE, close: CloseFn) -> Self

A request to close handle with a caller-supplied routine.

The escape hatch for a handle whose close routine this crate does not know about, so an unanticipated variant needs no change here.

§Safety

handle must be a live handle that the caller owns and gives up, and close must be the correct routine for it.

Source

pub fn handle(&self) -> HANDLE

The handle this request will close.

Source

pub fn perform(self) -> Outcome<()>

Performs the close on the calling thread.

Consumes the request, so a handle cannot be closed twice through this type.

§Errors

Returns the raw Win32 code, unaltered. The handle is closed either way: a failed close is not a close that can be retried.

Trait Implementations§

Source§

impl ConsumingRequest for CloseRequest

Source§

type Error = Win32Error

How performing it can fail.
Source§

type Output = ()

What performing the request produces.
Source§

fn perform(self) -> Outcome<()>

Performs the request on the calling thread, consuming it. Read more
Source§

impl Debug for CloseRequest

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Drop for CloseRequest

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more
Source§

impl Send for CloseRequest

Source§

impl Sync for CloseRequest

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.