1#ifndef _FDEVENT_H_ 2#define _FDEVENT_H_ 3 4#ifdef HAVE_CONFIG_H 5# include "config.h" 6#endif 7 8#include "settings.h" 9 10#if defined HAVE_STDINT_H 11# include <stdint.h> 12#elif defined HAVE_INTTYPES_H 13# include <inttypes.h> 14#endif 15 16#include <sys/types.h> 17 18/* select event-system */ 19 20#if defined(HAVE_EPOLL_CTL) && defined(HAVE_SYS_EPOLL_H) 21# define USE_LINUX_EPOLL 22#endif 23 24/* MacOS 10.3.x has poll.h under /usr/include/, all other unixes 25 * under /usr/include/sys/ */ 26#if defined HAVE_POLL && (defined(HAVE_SYS_POLL_H) || defined(HAVE_POLL_H)) 27# define USE_POLL 28#endif 29 30#if defined HAVE_SELECT 31# ifdef __WIN32 32# include <winsock2.h> 33# endif 34# define USE_SELECT 35# ifdef HAVE_SYS_SELECT_H 36# include <sys/select.h> 37# endif 38#endif 39 40#if defined HAVE_SYS_DEVPOLL_H && defined(__sun) 41# define USE_SOLARIS_DEVPOLL 42#endif 43 44#if defined HAVE_PORT_H && defined HAVE_PORT_CREATE && defined(__sun) 45# define USE_SOLARIS_PORT 46# include <port.h> 47#endif 48 49#if defined HAVE_SYS_EVENT_H && defined HAVE_KQUEUE 50# define USE_FREEBSD_KQUEUE 51#endif 52 53#if defined HAVE_LIBEV 54# define USE_LIBEV 55#endif 56 57struct server; 58 59typedef handler_t (*fdevent_handler)(struct server *srv, void *ctx, int revents); 60 61/* these are the POLL* values from <bits/poll.h> (linux poll) 62 */ 63 64#define FDEVENT_IN BV(0) 65#define FDEVENT_PRI BV(1) 66#define FDEVENT_OUT BV(2) 67#define FDEVENT_ERR BV(3) 68#define FDEVENT_HUP BV(4) 69#define FDEVENT_NVAL BV(5) 70 71typedef enum { FD_EVENT_TYPE_UNSET = -1, 72 FD_EVENT_TYPE_CONNECTION, 73 FD_EVENT_TYPE_FCGI_CONNECTION, 74 FD_EVENT_TYPE_DIRWATCH, 75 FD_EVENT_TYPE_CGI_CONNECTION 76} fd_event_t; 77 78typedef enum { FDEVENT_HANDLER_UNSET, 79 FDEVENT_HANDLER_SELECT, 80 FDEVENT_HANDLER_POLL, 81 FDEVENT_HANDLER_LINUX_SYSEPOLL, 82 FDEVENT_HANDLER_SOLARIS_DEVPOLL, 83 FDEVENT_HANDLER_SOLARIS_PORT, 84 FDEVENT_HANDLER_FREEBSD_KQUEUE, 85 FDEVENT_HANDLER_LIBEV 86} fdevent_handler_t; 87 88 89typedef struct _fdnode { 90 fdevent_handler handler; 91 void *ctx; 92 void *handler_ctx; 93 int fd; 94 int events; 95} fdnode; 96 97/** 98 * array of unused fd's 99 * 100 */ 101 102typedef struct { 103 int *ptr; 104 105 size_t used; 106 size_t size; 107} buffer_int; 108 109/** 110 * fd-event handler for select(), poll() and rt-signals on Linux 2.4 111 * 112 */ 113typedef struct fdevents { 114 struct server *srv; 115 fdevent_handler_t type; 116 117 fdnode **fdarray; 118 size_t maxfds; 119 120#ifdef USE_LINUX_EPOLL 121 int epoll_fd; 122 struct epoll_event *epoll_events; 123#endif 124#ifdef USE_POLL 125 struct pollfd *pollfds; 126 127 size_t size; 128 size_t used; 129 130 buffer_int unused; 131#endif 132#ifdef USE_SELECT 133 fd_set select_read; 134 fd_set select_write; 135 fd_set select_error; 136 137 fd_set select_set_read; 138 fd_set select_set_write; 139 fd_set select_set_error; 140 141 int select_max_fd; 142#endif 143#ifdef USE_SOLARIS_DEVPOLL 144 int devpoll_fd; 145 struct pollfd *devpollfds; 146#endif 147#ifdef USE_SOLARIS_PORT 148 port_event_t *port_events; 149#endif 150#ifdef USE_FREEBSD_KQUEUE 151 int kq_fd; 152 struct kevent *kq_results; 153#endif 154#ifdef USE_SOLARIS_PORT 155 int port_fd; 156#endif 157#ifdef USE_LIBEV 158 struct ev_loop *libev_loop; 159#endif 160 int (*reset)(struct fdevents *ev); 161 void (*free)(struct fdevents *ev); 162 163 int (*event_set)(struct fdevents *ev, int fde_ndx, int fd, int events); 164 int (*event_del)(struct fdevents *ev, int fde_ndx, int fd); 165 int (*event_get_revent)(struct fdevents *ev, size_t ndx); 166 int (*event_get_fd)(struct fdevents *ev, size_t ndx); 167 168 int (*event_next_fdndx)(struct fdevents *ev, int ndx); 169 170 int (*poll)(struct fdevents *ev, int timeout_ms); 171 172 int (*fcntl_set)(struct fdevents *ev, int fd); 173} fdevents; 174 175fdevents *fdevent_init(struct server *srv, size_t maxfds, fdevent_handler_t type); 176int fdevent_reset(fdevents *ev); /* "init" after fork() */ 177void fdevent_free(fdevents *ev); 178 179int fdevent_event_set(fdevents *ev, int *fde_ndx, int fd, int events); /* events can be FDEVENT_IN, FDEVENT_OUT or FDEVENT_IN | FDEVENT_OUT */ 180int fdevent_event_del(fdevents *ev, int *fde_ndx, int fd); 181int fdevent_event_get_revent(fdevents *ev, size_t ndx); 182int fdevent_event_get_fd(fdevents *ev, size_t ndx); 183fdevent_handler fdevent_get_handler(fdevents *ev, int fd); 184void * fdevent_get_context(fdevents *ev, int fd); 185 186int fdevent_event_next_fdndx(fdevents *ev, int ndx); 187 188int fdevent_poll(fdevents *ev, int timeout_ms); 189 190int fdevent_register(fdevents *ev, int fd, fdevent_handler handler, void *ctx); 191int fdevent_unregister(fdevents *ev, int fd); 192 193void fd_close_on_exec(int fd); 194int fdevent_fcntl_set(fdevents *ev, int fd); 195 196int fdevent_select_init(fdevents *ev); 197int fdevent_poll_init(fdevents *ev); 198int fdevent_linux_sysepoll_init(fdevents *ev); 199int fdevent_solaris_devpoll_init(fdevents *ev); 200int fdevent_solaris_port_init(fdevents *ev); 201int fdevent_freebsd_kqueue_init(fdevents *ev); 202int fdevent_libev_init(fdevents *ev); 203 204#endif 205