diff --git a/src/common/multiio.h b/src/common/multiio.h new file mode 100644 --- /dev/null +++ b/src/common/multiio.h @@ -0,0 +1,161 @@ +/* + Copyright 2010 Nathan Phillip Brink + + This file is a part of DistRen. + + DistRen is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + DistRen is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with DistRen. If not, see . + +*/ + +#ifndef DISTREN_MULTIIO_H +#define DISTREN_MULTIIO_H + +/** + @file multiio provides the event-oriented interface to accessing + sockets of different sorts. Its purpose is to provide a unified + interface around poll() which distrend and distren (client) would + both be able to use. This means supporting tracking file descriptors + from sockets of different types that must be handled differently, etc. + + This interface will be as simple as possible to provide greatest + flexibility and most ease of maintainence. + */ + +struct pollfd; + +/** + A socket type or classification. + + Each socket type is associated with a set of socket event handlers. + This allows, for example, a listen()/accept() socket to be distinguised + and reacted to differently from a read()/write() socket. It would also + allow one set of read()/write() sockets to be treated differently from + another set of read()/write() sockets. + */ +typedef int multiio_socket_type_t; + +struct multiio_context; +/** + The multiio_context a program is using. + + Each process should only use one multiio_context. Different types of events + should be handled through the use of different multiio_socket_type_t values. + */ +typedef struct multiio_context *multiio_context_t; + +/** + Initializes and returns a multiio_context. + */ +multiio_context_t multiio_context_new(); + +/** + Destroys and frees a multiio_context. + + @param context the context to destroy. + */ +int multiio_context_free(multiio_context_t context); + +/** + Call poll() on the registered sockets and react to events accordingly. + + @param context the context which sockets and handlers were registered with + */ +int multiio_poll(multiio_context_t context); + +/** + Registers a new socket type/classification for use with this multiio_context. + + @param context the multiio context to register this type with. + @param new_type a pointer to a type which this function will set to the value of + the newly registered type. The caller should record this type and use it for + future multiio_event_handler_register() calls, etc. + @return 0 on success, other on error + */ +int multiio_socket_type_register(multiio_context_t context, multiio_socket_type_t *new_type); + +/** + The basic event handler prototype. + + @param multiio the multiio context which is required for many multiio API functions. + @param fd the handle for which data was recieved. + @param revent the event that this handler was configured to respond to. + @param handler_data the same pointer named handler_data that was passed to multiio_event_handler_register(). This allows handlers to store general context information (i.e., pointer to a general settings struct) + @param socket_data the same pointer named socket_data that was passed to multiio_socket_add(). This allows handlers to access socket-specific information. + */ +typedef int(*multiio_event_handler_func_t)(multiio_context_t multiio, int fd, short revent, void *handler_data, void *socket_data); + +/** + Register a socket event handler for a specified socket type/class. + + Don't forget to register handlers for POLLERR, POLLHUP, and POLLNVAL. + You can probably just register one function to handle each of these + categories and clean up the socket. (and then don't forget to call + multiio_socket_del() :-p (or to free your per-socket pointers, etc.)). + + Handlers are called in the order they're registered. + + @param context the multiio_context + @param socket_type the type of socket this handler should be registered for. + @param event the poll() event on which this handler should be called. + @param handler_func the function to be called when event is matched. + @param handler_data a pointer that will be passed to handler_func whenever this event is matched for sockets of this socket_type. + */ +int multiio_event_handler_register(multiio_context_t context, multiio_socket_type_t socket_type, short event, multiio_event_handler_func_t handler_func, void *handler_data); + +/** + Register a socket of a specified type so that it may be checked for events + and the event handlers for its socket_type may be called. + + This function will set the socket into nonblocking mode. + + @param context the multiio context. + @param fd the socket. + @param socket_type the type/classification of this socket + @param socket_data a pointer to socket-specific data to pass to the multiio_event_handler_func_t. + @param events the poll() events with which this socket should be set to listen for. Certain events may be added or removed later using multiio_socket_event_enable() and multiio_socket_event_disable(). + */ +int multiio_socket_add(multiio_context_t context, int fd, multiio_socket_type_t socket_type, void *socket_data, short events); + +/** + Unregisters a socket from a multiio context + + @param context the context + @param fd the socket to remove + */ +int multiio_socket_del(multiio_context_t context, int fd); + +/** + Enable checking for the specified event for the specified socket. + + The specified socket must have been beforehand registered using multiio_socket_add(). + + @param context the multiio context + @param fd the socket for which checking of an event should be enabled + @param event the poll() event which should be enabled for this socket. + */ +int multiio_socket_event_enable(multiio_context_t context, int fd, short event); + +/** + Disable checking for the specified event for the specified socket. + + Disabling all events for a particular socket does not remove it from the + multiio context. + + @param context the multiio context + @param fd the socket for which checking of an event should be disabled + @param event the poll() event which should be disabled on this socket. + */ +int multiio_socket_event_disable(multiio_context_t context, int fd, short event); + +#endif /* DISTREN_MULTIIO_H */