/* * * Copyright 2014, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ #ifndef __GRPC_INTERNAL_IOMGR_FD_POSIX_H_ #define __GRPC_INTERNAL_IOMGR_FD_POSIX_H_ #include "src/core/iomgr/iomgr.h" #include "src/core/iomgr/pollset.h" #include #include #include typedef struct { grpc_iomgr_cb_func cb; void *cb_arg; int success; gpr_atm state; } grpc_fd_state; typedef struct grpc_fd grpc_fd; typedef struct grpc_fd_watcher { struct grpc_fd_watcher *next; struct grpc_fd_watcher *prev; grpc_pollset *pollset; grpc_fd *fd; } grpc_fd_watcher; struct grpc_fd { int fd; /* refst format: bit0: 1=active/0=orphaned bit1-n: refcount meaning that mostly we ref by two to avoid altering the orphaned bit, and just unref by 1 when we're ready to flag the object as orphaned */ gpr_atm refst; gpr_mu set_state_mu; gpr_atm shutdown; gpr_mu watcher_mu; grpc_fd_watcher watcher_root; grpc_fd_state readst; grpc_fd_state writest; grpc_iomgr_cb_func on_done; void *on_done_user_data; struct grpc_fd *freelist_next; }; /* Create a wrapped file descriptor. Requires fd is a non-blocking file descriptor. This takes ownership of closing fd. */ grpc_fd *grpc_fd_create(int fd); /* Releases fd to be asynchronously destroyed. on_done is called when the underlying file descriptor is definitely close()d. If on_done is NULL, no callback will be made. Requires: *fd initialized; no outstanding notify_on_read or notify_on_write. */ void grpc_fd_orphan(grpc_fd *fd, grpc_iomgr_cb_func on_done, void *user_data); /* Begin polling on an fd. Registers that the given pollset is interested in this fd - so that if read or writability interest changes, the pollset can be kicked to pick up that new interest. Return value is: (fd_needs_read? read_mask : 0) | (fd_needs_write? write_mask : 0) i.e. a combination of read_mask and write_mask determined by the fd's current interest in said events. Polling strategies that do not need to alter their behavior depending on the fd's current interest (such as epoll) do not need to call this function. */ gpr_uint32 grpc_fd_begin_poll(grpc_fd *fd, grpc_pollset *pollset, gpr_uint32 read_mask, gpr_uint32 write_mask, grpc_fd_watcher *rec); /* Complete polling previously started with grpc_fd_begin_poll */ void grpc_fd_end_poll(grpc_fd_watcher *rec); /* Return 1 if this fd is orphaned, 0 otherwise */ int grpc_fd_is_orphaned(grpc_fd *fd); /* Cause any current callbacks to error out with GRPC_CALLBACK_CANCELLED. */ void grpc_fd_shutdown(grpc_fd *fd); /* Register read interest, causing read_cb to be called once when fd becomes readable, on deadline specified by deadline, or on shutdown triggered by grpc_fd_shutdown. read_cb will be called with read_cb_arg when *fd becomes readable. read_cb is Called with status of GRPC_CALLBACK_SUCCESS if readable, GRPC_CALLBACK_TIMED_OUT if the call timed out, and CANCELLED if the call was cancelled. Requires:This method must not be called before the read_cb for any previous call runs. Edge triggered events are used whenever they are supported by the underlying platform. This means that users must drain fd in read_cb before calling notify_on_read again. Users are also expected to handle spurious events, i.e read_cb is called while nothing can be readable from fd */ void grpc_fd_notify_on_read(grpc_fd *fd, grpc_iomgr_cb_func read_cb, void *read_cb_arg); /* Exactly the same semantics as above, except based on writable events. */ void grpc_fd_notify_on_write(grpc_fd *fd, grpc_iomgr_cb_func write_cb, void *write_cb_arg); /* Notification from the poller to an fd that it has become readable or writable. If allow_synchronous_callback is 1, allow running the fd callback inline in this callstack, otherwise register an asynchronous callback and return */ void grpc_fd_become_readable(grpc_fd *fd, int allow_synchronous_callback); void grpc_fd_become_writable(grpc_fd *fd, int allow_synchronous_callback); /* Reference counting for fds */ void grpc_fd_ref(grpc_fd *fd); void grpc_fd_unref(grpc_fd *fd); void grpc_fd_global_init(void); void grpc_fd_global_shutdown(void); #endif /* __GRPC_INTERNAL_IOMGR_FD_POSIX_H_ */