1#include "fdevent.h" 2#include "buffer.h" 3#include "log.h" 4 5#include <sys/time.h> 6#include <sys/types.h> 7 8#include <unistd.h> 9#include <stdlib.h> 10#include <string.h> 11#include <errno.h> 12#include <signal.h> 13#include <fcntl.h> 14#include <assert.h> 15 16#ifdef USE_SELECT 17 18static int fdevent_select_reset(fdevents *ev) { 19 FD_ZERO(&(ev->select_set_read)); 20 FD_ZERO(&(ev->select_set_write)); 21 FD_ZERO(&(ev->select_set_error)); 22 ev->select_max_fd = -1; 23 24 return 0; 25} 26 27static int fdevent_select_event_del(fdevents *ev, int fde_ndx, int fd) { 28 if (fde_ndx < 0) return -1; 29 30 FD_CLR(fd, &(ev->select_set_read)); 31 FD_CLR(fd, &(ev->select_set_write)); 32 FD_CLR(fd, &(ev->select_set_error)); 33 34 return -1; 35} 36 37static int fdevent_select_event_set(fdevents *ev, int fde_ndx, int fd, int events) { 38 UNUSED(fde_ndx); 39 40 /* we should be protected by max-fds, but you never know */ 41 force_assert(fd < ((int)FD_SETSIZE)); 42 43 if (events & FDEVENT_IN) { 44 FD_SET(fd, &(ev->select_set_read)); 45 } else { 46 FD_CLR(fd, &(ev->select_set_read)); 47 } 48 if (events & FDEVENT_OUT) { 49 FD_SET(fd, &(ev->select_set_write)); 50 } else { 51 FD_CLR(fd, &(ev->select_set_write)); 52 } 53 FD_SET(fd, &(ev->select_set_error)); 54 55 if (fd > ev->select_max_fd) ev->select_max_fd = fd; 56 57 return fd; 58} 59 60static int fdevent_select_poll(fdevents *ev, int timeout_ms) { 61 struct timeval tv; 62 63 tv.tv_sec = timeout_ms / 1000; 64 tv.tv_usec = (timeout_ms % 1000) * 1000; 65 66 ev->select_read = ev->select_set_read; 67 ev->select_write = ev->select_set_write; 68 ev->select_error = ev->select_set_error; 69 70 return select(ev->select_max_fd + 1, &(ev->select_read), &(ev->select_write), &(ev->select_error), &tv); 71} 72 73static int fdevent_select_event_get_revent(fdevents *ev, size_t ndx) { 74 int revents = 0; 75 76 if (FD_ISSET(ndx, &(ev->select_read))) { 77 revents |= FDEVENT_IN; 78 } 79 if (FD_ISSET(ndx, &(ev->select_write))) { 80 revents |= FDEVENT_OUT; 81 } 82 if (FD_ISSET(ndx, &(ev->select_error))) { 83 revents |= FDEVENT_ERR; 84 } 85 86 return revents; 87} 88 89static int fdevent_select_event_get_fd(fdevents *ev, size_t ndx) { 90 UNUSED(ev); 91 92 return ndx; 93} 94 95static int fdevent_select_event_next_fdndx(fdevents *ev, int ndx) { 96 int i; 97 98 i = (ndx < 0) ? 0 : ndx + 1; 99 100 for (; i < ev->select_max_fd + 1; i++) { 101 if (FD_ISSET(i, &(ev->select_read))) return i; 102 if (FD_ISSET(i, &(ev->select_write))) return i; 103 if (FD_ISSET(i, &(ev->select_error))) return i; 104 } 105 106 return -1; 107} 108 109int fdevent_select_init(fdevents *ev) { 110 ev->type = FDEVENT_HANDLER_SELECT; 111#define SET(x) \ 112 ev->x = fdevent_select_##x; 113 114 SET(reset); 115 SET(poll); 116 117 SET(event_del); 118 SET(event_set); 119 120 SET(event_next_fdndx); 121 SET(event_get_fd); 122 SET(event_get_revent); 123 124 return 0; 125} 126 127#else 128int fdevent_select_init(fdevents *ev) { 129 UNUSED(ev); 130 131 return -1; 132} 133#endif 134