src/lib/transport_fd.h
branchnew-lib-errors
changeset 219 cefec18b8268
parent 176 6750d50ee8cd
equal deleted inserted replaced
218:5229a5d098b2 219:cefec18b8268
       
     1 #ifndef LIBQMSK_TRANSPORT_FD_H
       
     2 #define LIBQMSK_TRANSPORT_FD_H
       
     3 
       
     4 /**
       
     5  * @file
       
     6  *
       
     7  * Support for transport implementations that use POSIX file descriptor streams.
       
     8  *
       
     9  * This provides the read/write methods, as well as functions to implement the event-based behaviour.
       
    10  */
       
    11 #include "transport_internal.h"
       
    12 
       
    13 #include <event2/event.h>
       
    14 #include <stdbool.h>
       
    15 
       
    16 // forward-declare
       
    17 struct transport_fd;
       
    18 
       
    19 /**
       
    20  * Our transport_type
       
    21  */
       
    22 extern const struct transport_type transport_fd_type;
       
    23 
       
    24 /**
       
    25  * Low-level callback
       
    26  */
       
    27 typedef void (*transport_fd_callback_func) (struct transport_fd *fd, short what, void *arg);
       
    28 
       
    29 /**
       
    30  * The fd-based transport implementation
       
    31  */
       
    32 struct transport_fd {
       
    33     /** Base transport state */
       
    34     struct transport base;
       
    35 
       
    36     /** Libevent base to use */
       
    37     struct event_base *ev_base;
       
    38     
       
    39     /** OS file descriptor */
       
    40     evutil_socket_t fd;
       
    41 
       
    42     /** IO events */
       
    43     struct event *ev_read, *ev_write;
       
    44 
       
    45     /** Low-level callback */
       
    46     transport_fd_callback_func cb_func;
       
    47 
       
    48     /** Callback context argument */
       
    49     void *cb_arg;
       
    50 
       
    51 };
       
    52 
       
    53 /**
       
    54  * Get a transport_t pointer from a transport_fd
       
    55  */
       
    56 #define TRANSPORT_FD_BASE(tp_ptr) (&(tp_ptr)->base)
       
    57 
       
    58 /**
       
    59  * Invalid OS FD
       
    60  */
       
    61 #define TRANSPORT_FD_INVALID ((evutil_socket_t) -1)
       
    62 
       
    63 /**
       
    64  * Implementation of transport_methods::read
       
    65  */
       
    66 err_t transport_fd__read (transport_t *transport, void *buf, size_t *len, error_t *err);
       
    67 
       
    68 /**
       
    69  * Implementation of transport_methods::write.
       
    70  *
       
    71  * If this gets EAGAIN, it will automatically enable the write event, unless masked out.
       
    72  */
       
    73 err_t transport_fd__write (transport_t *transport, const void *buf, size_t *len, error_t *err);
       
    74 
       
    75 /**
       
    76  * Implementation of transport_methods::events.
       
    77  *
       
    78  * For TRANSPORT_READ, this will simply apply enable/disable as given.
       
    79  *
       
    80  * For TRANSPORT_WRITE, the write event will only be enabled if given in the mask, *and* the ev_write event is currently
       
    81  * active (via transport_fd_methods_write()); otherwise, the write event will not be enabled.
       
    82  */
       
    83 err_t transport_fd__events (transport_t *transport, short mask, error_t *err);
       
    84 
       
    85 /**
       
    86  * Implementation of transport_methods::deinit.
       
    87  *
       
    88  * This simply calls transport_fd_deinit().
       
    89  */
       
    90 void transport_fd__deinit (transport_t *transport);
       
    91 
       
    92 /**
       
    93  * A transport_fd_callback_func that simply invokes the transport_callback user functions.
       
    94  *
       
    95  * Register with a NULL cb_arg.
       
    96  */
       
    97 void transport_fd_callback_user (struct transport_fd *fd, short what, void *arg);
       
    98 
       
    99 
       
   100 
       
   101 
       
   102 /**
       
   103  * Initialize the transport_fd to use the given, connected fd, or TRANSPORT_FD_INVALID if we don't yet have an fd.
       
   104  *
       
   105  * It is an error to call this if the transport_fd already has an fd set
       
   106  *
       
   107  * @param fd the transport_fd state
       
   108  * @param ev_base the libevent base to use
       
   109  * @param _fd the OS file descriptor, or TRANSPORT_FD_INVALID
       
   110  */
       
   111 void transport_fd_init (struct transport_fd *fd, struct event_base *ev_base, int _fd);
       
   112 
       
   113 /**
       
   114  * Set the fd's nonblocking mode using fcntl.
       
   115  */
       
   116 err_t transport_fd_nonblock (struct transport_fd *fd, bool nonblock);
       
   117 
       
   118 /**
       
   119  * Set or replace the fd's event callback. The callback will not be enabled.
       
   120  *
       
   121  * The transport must have a valid fd bound to it.
       
   122  */
       
   123 err_t transport_fd_setup (struct transport_fd *fd, transport_fd_callback_func cb_func, void *cb_arg);
       
   124 
       
   125 /**
       
   126  * Enable the specified events, any of { TRANSPORT_READ, TRANSPORT_WRITE }.
       
   127  */
       
   128 err_t transport_fd_enable (struct transport_fd *fd, short mask);
       
   129 
       
   130 /**
       
   131  * Disable the specified events, any of { TRANSPORT_READ, TRANSPORT_WRITE }.
       
   132  */
       
   133 err_t transport_fd_disable (struct transport_fd *fd, short mask);
       
   134 
       
   135 /**
       
   136  * Set the enable/disable state of our events to the given mask.
       
   137  */
       
   138 err_t transport_fd_events (struct transport_fd *fd, short mask);
       
   139 
       
   140 /**
       
   141  * Remove any old event callback present, so it will not be called anymore.
       
   142  *
       
   143  * It is perfectly safe to call this without any callbacks installed.
       
   144  */
       
   145 void transport_fd_clear (struct transport_fd *fd);
       
   146 
       
   147 /**
       
   148  * Setup and enable the default event handlers for transport operation, that is, use transport_fd_callback_user as the 
       
   149  * callback and enable TRANSPORT_READ, unless masked out.
       
   150  */
       
   151 err_t transport_fd_defaults (struct transport_fd *fd);
       
   152 
       
   153 /**
       
   154  * Replace the old fd with a new one, maintaining any event callbacks set with transport_fd_callback. If any events were
       
   155  * enabled before, they are not enabled anymore.
       
   156  */
       
   157 err_t transport_fd_set (struct transport_fd *fd, int _fd, error_t *err);
       
   158 
       
   159 /**
       
   160  * Close an opened fd, releasing all resources within our state.
       
   161  */
       
   162 err_t transport_fd_close (struct transport_fd *fd, error_t *err);
       
   163 
       
   164 /**
       
   165  * Deinitialize the transport_fd.
       
   166  *
       
   167  * This logs a warning if the close() fails.
       
   168  *
       
   169  * XXX: this may actually block, I think? SO_LINGER?
       
   170  */
       
   171 void transport_fd_deinit (struct transport_fd *fd);
       
   172 
       
   173 #endif