summaryrefslogtreecommitdiff
path: root/usr.sbin/nsd/netio.h
diff options
context:
space:
mode:
authorJakob Schlyter <jakob@cvs.openbsd.org>2010-01-15 19:25:09 +0000
committerJakob Schlyter <jakob@cvs.openbsd.org>2010-01-15 19:25:09 +0000
commitd2081ac134d2d350ed92374b12613330132619c9 (patch)
tree511f9a412b24160516c7d3d29111801f9fa1bf35 /usr.sbin/nsd/netio.h
parentefe15de128add506fb4055690c47221eb73d6346 (diff)
NSD v3.2.4
Diffstat (limited to 'usr.sbin/nsd/netio.h')
-rw-r--r--usr.sbin/nsd/netio.h182
1 files changed, 182 insertions, 0 deletions
diff --git a/usr.sbin/nsd/netio.h b/usr.sbin/nsd/netio.h
new file mode 100644
index 00000000000..99d9c316aa3
--- /dev/null
+++ b/usr.sbin/nsd/netio.h
@@ -0,0 +1,182 @@
+/*
+ * netio.h -- network I/O support.
+ *
+ * Copyright (c) 2001-2006, NLnet Labs. All rights reserved.
+ *
+ * See LICENSE for the license.
+ *
+ *
+ * The netio module implements event based I/O handling using
+ * pselect(2). Multiple event handlers can wait for a certain event
+ * to occur simultaneously. Each event handler is called when an
+ * event occurs that the event handler has indicated that it is
+ * willing to handle.
+ *
+ * There are four types of events that can be handled:
+ *
+ * NETIO_EVENT_READ: reading will not block.
+ * NETIO_EVENT_WRITE: writing will not block.
+ * NETIO_EVENT_EXCEPT: an exception occurred.
+ * NETIO_EVENT_TIMEOUT: the timeout expired.
+ *
+ * A file descriptor must be specified if the handler is interested in
+ * the first three event types. A timeout must be specified if the
+ * event handler is interested in timeouts. These event types can be
+ * OR'ed together if the handler is willing to handle multiple types
+ * of events.
+ *
+ * The special event type NETIO_EVENT_NONE is available if you wish to
+ * temporarily disable the event handler without removing and adding
+ * the handler to the netio structure.
+ *
+ * The event callbacks are free to modify the netio_handler_type
+ * structure to change the file descriptor, timeout, event types, user
+ * data, or handler functions.
+ *
+ * The main loop of the program must call netio_dispatch to check for
+ * events and dispatch them to the handlers. An additional timeout
+ * can be specified as well as the signal mask to install while
+ * blocked in pselect(2).
+ */
+
+#ifndef _NETIO_H_
+#define _NETIO_H_
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#include <signal.h>
+
+#include "region-allocator.h"
+
+/*
+ * The type of events a handler is interested in. These can be OR'ed
+ * together to specify multiple event types.
+ */
+enum netio_event_types {
+ NETIO_EVENT_NONE = 0,
+ NETIO_EVENT_READ = 1,
+ NETIO_EVENT_WRITE = 2,
+ NETIO_EVENT_EXCEPT = 4,
+ NETIO_EVENT_TIMEOUT = 8
+};
+typedef enum netio_event_types netio_event_types_type;
+
+typedef struct netio netio_type;
+typedef struct netio_handler netio_handler_type;
+typedef struct netio_handler_list netio_handler_list_type;
+
+struct netio
+{
+ region_type *region;
+ netio_handler_list_type *handlers;
+ netio_handler_list_type *deallocated;
+
+ /*
+ * Cached value of the current time. The cached value is
+ * cleared at the start of netio_dispatch to calculate the
+ * relative timeouts of the event handlers and after calling
+ * pselect(2) so handlers can use it to calculate a new
+ * absolute timeout.
+ *
+ * Use netio_current_time() to read the current time.
+ */
+ int have_current_time;
+ struct timespec cached_current_time;
+
+ /*
+ * Next handler in the dispatch. Only valid during callbacks.
+ * To make sure that deletes respect the state of the iterator.
+ */
+ netio_handler_list_type *dispatch_next;
+};
+
+typedef void (*netio_event_handler_type)(netio_type *netio,
+ netio_handler_type *handler,
+ netio_event_types_type event_types);
+
+struct netio_handler
+{
+ /*
+ * The file descriptor that should be checked for events. If
+ * the file descriptor is negative only timeout events are
+ * checked for.
+ */
+ int fd;
+
+ /*
+ * The time when no events should be checked for and the
+ * handler should be called with the NETIO_EVENT_TIMEOUT
+ * event type. Unlike most timeout parameters the time should
+ * be absolute, not relative!
+ */
+ struct timespec *timeout;
+
+ /*
+ * Additional user data.
+ */
+ void *user_data;
+
+ /*
+ * The type of events that should be checked for. These types
+ * can be OR'ed together to wait for multiple types of events.
+ */
+ netio_event_types_type event_types;
+
+ /*
+ * The event handler. The event_types parameter contains the
+ * OR'ed set of event types that actually triggered. The
+ * event handler is allowed to modify this handler object.
+ * The event handler SHOULD NOT block.
+ */
+ netio_event_handler_type event_handler;
+};
+
+
+/*
+ * Create a new netio instance using the specified REGION. The netio
+ * instance is cleaned up when the REGION is deallocated.
+ */
+netio_type *netio_create(region_type *region);
+
+/*
+ * Add a new HANDLER to NETIO.
+ */
+void netio_add_handler(netio_type *netio, netio_handler_type *handler);
+
+/*
+ * Remove the HANDLER from NETIO.
+ */
+void netio_remove_handler(netio_type *netio, netio_handler_type *handler);
+
+/*
+ * Retrieve the current time (using gettimeofday(2).
+ */
+const struct timespec *netio_current_time(netio_type *netio);
+
+/*
+ * Check for events and dispatch them to the handlers. If TIMEOUT is
+ * specified it specifies the maximum time to wait for an event to
+ * arrive. SIGMASK is passed to the underlying pselect(2) call.
+ * Returns the number of non-timeout events dispatched, 0 on timeout,
+ * and -1 on error (with errno set appropriately).
+ */
+int netio_dispatch(netio_type *netio,
+ const struct timespec *timeout,
+ const sigset_t *sigmask);
+
+
+#ifdef __cplusplus
+inline netio_event_types_type
+operator | (netio_event_types_type lhs, netio_event_types_type rhs) {
+ return (netio_event_types_type) (lhs | rhs);
+}
+inline netio_event_types_type
+operator |= (netio_event_types_type &lhs, netio_event_types_type rhs) {
+ lhs = (netio_event_types_type) (lhs | rhs);
+ return lhs;
+}
+#endif /* __cplusplus */
+
+#endif /* _NETIO_H_ */