21 int pselect(
int n, fd_set* readfds, fd_set* writefds, fd_set* exceptfds,
22 const struct timespec* timeout,
const sigset_t* sigmask);
24 #include <sys/select.h>
28 #define NANOSECONDS_PER_SECOND 1000000000L
30 static const char* netio_str =
"netio";
61 if (!netio || !handler) {
87 if (!netio || !handler) {
90 for (lptr = &netio->
handlers; *lptr; lptr = &(*lptr)->
next) {
91 if ((*lptr)->handler == handler) {
112 timeval_to_timespec(
struct timespec* left,
const struct timeval* right)
114 left->tv_sec = right->tv_sec;
115 left->tv_nsec = 1000 * right->tv_usec;
124 timespec_compare(
const struct timespec* left,
125 const struct timespec* right)
127 if (left->tv_sec < right->tv_sec) {
129 }
else if (left->tv_sec > right->tv_sec) {
131 }
else if (left->tv_nsec < right->tv_nsec) {
133 }
else if (left->tv_nsec > right->tv_nsec) {
147 left->tv_sec += right->tv_sec;
148 left->tv_nsec += right->tv_nsec;
162 timespec_subtract(
struct timespec* left,
const struct timespec* right)
164 left->tv_sec -= right->tv_sec;
165 left->tv_nsec -= right->tv_nsec;
166 if (left->tv_nsec < 0L) {
178 const struct timespec*
181 struct timeval current_timeval;
184 if (gettimeofday(¤t_timeval, NULL) == -1) {
186 "gettimeofday() failed (%s)", netio_str,
204 const sigset_t* sigmask)
206 fd_set readfds, writefds, exceptfds;
208 int have_timeout = 0;
209 struct timespec minimum_timeout;
223 memcpy(&minimum_timeout, timeout,
sizeof(
struct timespec));
233 if (handler->
fd >= 0 && handler->
fd < (
int) FD_SETSIZE) {
234 if (handler->
fd > max_fd) {
235 max_fd = handler->
fd;
238 FD_SET(handler->
fd, &readfds);
241 FD_SET(handler->
fd, &writefds);
244 FD_SET(handler->
fd, &exceptfds);
249 struct timespec relative;
250 relative.tv_sec = handler->
timeout->tv_sec;
251 relative.tv_nsec = handler->
timeout->tv_nsec;
255 timespec_compare(&relative, &minimum_timeout) < 0) {
257 minimum_timeout.tv_sec = relative.tv_sec;
258 minimum_timeout.tv_nsec = relative.tv_nsec;
259 timeout_handler = handler;
264 if (have_timeout && minimum_timeout.tv_sec < 0) {
269 ods_log_debug(
"[%s] dispatch timeout event without checking for "
270 "other events", netio_str);
271 if (timeout_handler &&
273 timeout_handler->event_handler(netio, timeout_handler,
279 rc =
pselect(max_fd + 1, &readfds, &writefds, &exceptfds,
280 have_timeout ? &minimum_timeout : NULL, sigmask);
282 if(errno == EINVAL || errno == EACCES || errno == EBADF) {
295 "expired", netio_str);
300 if (timeout_handler &&
302 timeout_handler->event_handler(netio, timeout_handler,
313 for (l = netio->
handlers; l && rc; ) {
316 if (handler->
fd >= 0 && handler->
fd < (
int) FD_SETSIZE) {
318 if (FD_ISSET(handler->
fd, &readfds)) {
320 FD_CLR(handler->
fd, &readfds);
323 if (FD_ISSET(handler->
fd, &writefds)) {
325 FD_CLR(handler->
fd, &writefds);
328 if (FD_ISSET(handler->
fd, &exceptfds)) {
330 FD_CLR(handler->
fd, &exceptfds);