blob: e0f59d70e4310c708c47405f8a61e962aafdbe57 [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//! Type-safe bindings for Zircon pmt objects.
use crate::ok;
use crate::{AsHandleRef, Handle, HandleBased, HandleRef, Status};
use fuchsia_zircon_sys as sys;
use std::mem;
/// An object representing a Zircon Pinned Memory Token.
/// See [PMT Documentation](https://fuchsia.dev/fuchsia-src/reference/kernel_objects/pinned_memory_token) for details.
///
/// As essentially a subtype of `Handle`, it can be freely interconverted.
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[repr(transparent)]
pub struct Pmt(Handle);
impl_handle_based!(Pmt);
impl Pmt {
// Unpins a Pinned Memory Token.
// Wraps the
// [`zx_pmt_unpin`](https://fuchsia.dev/fuchsia-src/reference/syscalls/pmt_unpin) system call to unpin a pmt.
pub fn unpin(self) -> Result<(), Status> {
let status = unsafe { sys::zx_pmt_unpin(self.raw_handle()) };
// According to the syscall documentation, after calling `zx_pmt_unpin`,
// the pmt handle cannot be used anymore, not even for `zx_handle_close`.
// This is also true even if the function returns an error.
mem::forget(self);
ok(status)?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Vmo;
#[test]
fn pmt_unpin_invalid_handle() {
let pmt = Pmt::from(Handle::invalid());
let status = pmt.unpin();
assert_eq!(status, Err(Status::BAD_HANDLE));
}
#[test]
fn pmt_unpin_wrong_handle() {
let vmo = Vmo::create(0).unwrap();
let pmt = unsafe { Pmt::from(Handle::from_raw(vmo.into_raw())) };
let status = pmt.unpin();
assert_eq!(status, Err(Status::WRONG_TYPE));
}
}