blob: 0bb613c4569dd6e1d3e239d3f696241d4622b738 [file] [log] [blame]
// Copyright 2016 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.
#include <poll.h>
#include <stdbool.h>
#include <stdlib.h>
#include <magenta/syscalls.h>
#include <mxio/io.h>
#include "private.h"
typedef struct mxwio mxwio_t;
struct mxwio {
// base mxio io object
mxio_t io;
// arbitrary handle
mx_handle_t h;
// signals that cause POLLIN
mx_signals_t signals_in;
// signals that cause POLLOUT
mx_signals_t signals_out;
// if true, don't close handle on close() op
bool shared_handle;
};
static mx_status_t mxwio_close(mxio_t* io) {
mxwio_t* wio = (mxwio_t*)io;
mx_handle_t h = wio->h;
wio->h = MX_HANDLE_INVALID;
if (!wio->shared_handle) {
mx_handle_close(h);
}
return MX_OK;
}
static void mxwio_wait_begin(mxio_t* io, uint32_t events, mx_handle_t* handle,
mx_signals_t* _signals) {
mxwio_t* wio = (void*)io;
*handle = wio->h;
mx_signals_t signals = 0;
if (events & POLLIN) {
signals |= wio->signals_in;
}
if (events & POLLOUT) {
signals |= wio->signals_out;
}
*_signals = signals;
}
static void mxwio_wait_end(mxio_t* io, mx_signals_t signals, uint32_t* _events) {
mxwio_t* wio = (void*)io;
uint32_t events = 0;
if (signals & wio->signals_in) {
events |= POLLIN;
}
if (signals & wio->signals_out) {
events |= POLLOUT;
}
*_events = events;
}
static mxio_ops_t mxio_waitable_ops = {
.read = mxio_default_read,
.read_at = mxio_default_read_at,
.write = mxio_default_write,
.write_at = mxio_default_write_at,
.recvfrom = mxio_default_recvfrom,
.sendto = mxio_default_sendto,
.recvmsg = mxio_default_recvmsg,
.sendmsg = mxio_default_sendmsg,
.seek = mxio_default_seek,
.misc = mxio_default_misc,
.close = mxwio_close,
.open = mxio_default_open,
.clone = mxio_default_clone,
.ioctl = mxio_default_ioctl,
.unwrap = mxio_default_unwrap,
.shutdown = mxio_default_shutdown,
.wait_begin = mxwio_wait_begin,
.wait_end = mxwio_wait_end,
.posix_ioctl = mxio_default_posix_ioctl,
};
mxio_t* mxio_waitable_create(mx_handle_t h, mx_signals_t signals_in,
mx_signals_t signals_out, bool shared_handle) {
mxwio_t* wio = calloc(1, sizeof(*wio));
if (wio == NULL) {
if (!shared_handle) {
mx_handle_close(h);
}
return NULL;
}
wio->io.ops = &mxio_waitable_ops;
wio->io.magic = MXIO_MAGIC;
wio->io.refcount = 1;
wio->io.flags |= MXIO_FLAG_WAITABLE;
wio->h = h;
wio->signals_in = signals_in;
wio->signals_out = signals_out;
wio->shared_handle = shared_handle;
return &wio->io;
}