use {Port, Rights, Signals, Status, Time, WaitAsyncOpts, ok, sys};
use std::marker::PhantomData;
use std::mem;
#[derive(Debug, Eq, PartialEq, Hash)]
pub struct Handle(sys::zx_handle_t);
impl AsHandleRef for Handle {
fn as_handle_ref(&self) -> HandleRef {
HandleRef { handle: self.0, phantom: Default::default() }
}
}
impl HandleBased for Handle {}
impl Drop for Handle {
fn drop(&mut self) {
if self.0 != sys::ZX_HANDLE_INVALID {
unsafe { sys::zx_handle_close(self.0) };
}
}
}
impl Handle {
pub fn invalid() -> Handle {
Handle(sys::ZX_HANDLE_INVALID)
}
pub unsafe fn from_raw(raw: sys::zx_handle_t) -> Handle {
Handle(raw)
}
pub fn is_invalid(&self) -> bool {
self.0 == sys::ZX_HANDLE_INVALID
}
pub fn replace(self, rights: Rights) -> Result<Handle, Status> {
let handle = self.0;
let mut out = 0;
let status = unsafe { sys::zx_handle_replace(handle, rights.bits(), &mut out) };
ok(status).map(|()| Handle(out))
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct HandleRef<'a> {
handle: sys::zx_handle_t,
phantom: PhantomData<&'a sys::zx_handle_t>,
}
impl<'a> HandleRef<'a> {
pub fn raw_handle(&self) -> sys::zx_handle_t {
self.handle
}
pub fn duplicate(&self, rights: Rights) -> Result<Handle, Status> {
let handle = self.handle;
let mut out = 0;
let status = unsafe { sys::zx_handle_duplicate(handle, rights.bits(), &mut out) };
ok(status).map(|()| Handle(out))
}
pub fn signal(&self, clear_mask: Signals, set_mask: Signals) -> Result<(), Status> {
let handle = self.handle;
let status = unsafe { sys::zx_object_signal(handle, clear_mask.bits(), set_mask.bits()) };
ok(status)
}
pub fn wait(&self, signals: Signals, deadline: Time) -> Result<Signals, Status> {
let handle = self.handle;
let mut pending = Signals::empty().bits();
let status = unsafe {
sys::zx_object_wait_one(handle, signals.bits(), deadline.nanos(), &mut pending)
};
ok(status).map(|()| Signals::from_bits_truncate(pending))
}
pub fn wait_async(&self, port: &Port, key: u64, signals: Signals, options: WaitAsyncOpts)
-> Result<(), Status>
{
let handle = self.handle;
let status = unsafe {
sys::zx_object_wait_async(
handle, port.raw_handle(), key, signals.bits(), options as u32)
};
ok(status)
}
}
pub trait AsHandleRef {
fn as_handle_ref(&self) -> HandleRef;
fn raw_handle(&self) -> sys::zx_handle_t {
self.as_handle_ref().raw_handle()
}
fn signal_handle(&self, clear_mask: Signals, set_mask: Signals) -> Result<(), Status> {
self.as_handle_ref().signal(clear_mask, set_mask)
}
fn wait_handle(&self, signals: Signals, deadline: Time) -> Result<Signals, Status> {
self.as_handle_ref().wait(signals, deadline)
}
fn wait_async_handle(&self, port: &Port, key: u64, signals: Signals, options: WaitAsyncOpts)
-> Result<(), Status>
{
self.as_handle_ref().wait_async(port, key, signals, options)
}
}
impl<'a> AsHandleRef for HandleRef<'a> {
fn as_handle_ref(&self) -> HandleRef { *self }
}
pub trait HandleBased: AsHandleRef + From<Handle> + Into<Handle> {
fn duplicate_handle(&self, rights: Rights) -> Result<Self, Status> {
self.as_handle_ref().duplicate(rights).map(|handle| Self::from(handle))
}
fn replace_handle(self, rights: Rights) -> Result<Self, Status> {
<Self as Into<Handle>>::into(self)
.replace(rights).map(|handle| Self::from(handle))
}
fn into_handle(self) -> Handle {
self.into()
}
fn into_raw(self) -> sys::zx_handle_t {
let h = self.into_handle();
let r = h.0;
mem::forget(h);
r
}
fn from_handle(handle: Handle) -> Self {
Self::from(handle)
}
fn into_handle_based<H: HandleBased>(self) -> H {
H::from_handle(self.into_handle())
}
fn from_handle_based<H: HandleBased>(h: H) -> Self {
Self::from_handle(h.into_handle())
}
}
pub trait Peered: HandleBased {
fn signal_peer(&self, clear_mask: Signals, set_mask: Signals) -> Result<(), Status> {
let handle = self.as_handle_ref().handle;
let status = unsafe {
sys::zx_object_signal_peer(handle, clear_mask.bits(), set_mask.bits())
};
ok(status)
}
}
pub trait Cookied: HandleBased {
fn get_cookie(&self, scope: &HandleRef) -> Result<u64, Status> {
let handle = self.as_handle_ref().handle;
let mut cookie = 0;
let status = unsafe { sys::zx_object_get_cookie(handle, scope.handle, &mut cookie) };
ok(status).map(|()| cookie)
}
fn set_cookie(&self, scope: &HandleRef, cookie: u64) -> Result<(), Status> {
let handle = self.as_handle_ref().handle;
let status = unsafe { sys::zx_object_set_cookie(handle, scope.handle, cookie) };
ok(status)
}
}