poll.cpp
Go to the documentation of this file.
00001 
00009 /*****************************************************************************
00010 ** Includes
00011 *****************************************************************************/
00012 
00013 #include "../../include/ecl/io/poll.hpp"
00014 
00015 /*****************************************************************************
00016 ** Namespaces
00017 *****************************************************************************/
00018 
00019 namespace ecl {
00020 
00021 /*****************************************************************************
00022 ** Implementation
00023 *****************************************************************************/
00024 
00025 int poll_sockets(socket_pollfd *fds, nfds_t nfds, int timeout) {
00026 #if defined(ECL_IS_WIN32)
00027         fd_set readfds, writefds, exceptfds;
00028         struct timeval tv, *ptv;
00029         socket_descriptor max_fd;
00030         int rc;
00031         nfds_t i;
00032 
00033         if (fds == NULL) {
00034                 errno = EFAULT;
00035                 return -1;
00036         }
00037 
00038         FD_ZERO (&readfds);
00039         FD_ZERO (&writefds);
00040         FD_ZERO (&exceptfds);
00041 
00042         /*********************
00043         ** Compute fd sets
00044         **********************/
00045         // also find the largest descriptor.
00046         for (rc = -1, max_fd = 0, i = 0; i < nfds; i++) {
00047                 if (fds[i].fd == INVALID_SOCKET) {
00048                         continue;
00049                 }
00050                 if (fds[i].events & (POLLIN | POLLRDNORM)) {
00051                         FD_SET (fds[i].fd, &readfds);
00052                 }
00053                 if (fds[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND)) {
00054                         FD_SET (fds[i].fd, &writefds);
00055                 }
00056                 if (fds[i].events & (POLLPRI | POLLRDBAND)) {
00057                         FD_SET (fds[i].fd, &exceptfds);
00058                 }
00059                 if (fds[i].fd > max_fd &&
00060                           (fds[i].events & (POLLIN | POLLOUT | POLLPRI |
00061                                                                 POLLRDNORM | POLLRDBAND |
00062                                                                 POLLWRNORM | POLLWRBAND))) {
00063                         max_fd = fds[i].fd;
00064                         rc = 0;
00065                 }
00066         }
00067 
00068         if (rc == -1) {
00069                 errno = EINVAL;
00070                 return -1;
00071         }
00072         /*********************
00073         ** Setting the timeout
00074         **********************/
00075         if (timeout < 0) {
00076                 ptv = NULL;
00077         } else {
00078                 ptv = &tv;
00079                 if (timeout == 0) {
00080                         tv.tv_sec = 0;
00081                         tv.tv_usec = 0;
00082                 } else {
00083                         tv.tv_sec = timeout / 1000;
00084                         tv.tv_usec = (timeout % 1000) * 1000;
00085                 }
00086         }
00087 
00088         rc = select (max_fd + 1, &readfds, &writefds, &exceptfds, ptv);
00089         if (rc < 0) {
00090                 return -1;
00091         } else if ( rc == 0 ) {
00092                 return 0;
00093         }
00094 
00095         for (rc = 0, i = 0; i < nfds; i++) {
00096                 if (fds[i].fd != INVALID_SOCKET) {
00097                         fds[i].revents = 0;
00098 
00099                         if (FD_ISSET(fds[i].fd, &readfds)) {
00100                                 int save_errno = errno;
00101                                 char data[64] = {0};
00102                                 int ret;
00103 
00104                                 /* support for POLLHUP */
00105                                 // just check if there's incoming data, without removing it from the queue.
00106                                 ret = recv(fds[i].fd, data, 64, MSG_PEEK);
00107                                 #ifdef WIN32
00108                                 if ((ret == -1) &&
00109                                                 (errno == WSAESHUTDOWN || errno == WSAECONNRESET ||
00110                                                 (errno == WSAECONNABORTED) || errno == WSAENETRESET))
00111                                 #else
00112                                 if ((ret == -1) &&
00113                                                 (errno == ESHUTDOWN || errno == ECONNRESET ||
00114                                                 (errno == ECONNABORTED) || errno == ENETRESET))
00115                                 #endif
00116                                 {
00117                                         fds[i].revents |= POLLHUP;
00118                                 } else {
00119                                         fds[i].revents |= fds[i].events & (POLLIN | POLLRDNORM);
00120                                 }
00121                                 errno = save_errno;
00122                         }
00123                         if (FD_ISSET(fds[i].fd, &writefds)) {
00124                                 fds[i].revents |= fds[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND);
00125                         }
00126 
00127                         if (FD_ISSET(fds[i].fd, &exceptfds)) {
00128                                 fds[i].revents |= fds[i].events & (POLLPRI | POLLRDBAND);
00129                         }
00130 
00131                         if (fds[i].revents & ~POLLHUP) {
00132                                 rc++;
00133                         }
00134                 } else {
00135                                 fds[i].revents = POLLNVAL;
00136                 }
00137         }
00138         return rc;
00139 #else
00140         // should really put in a cmake check to check that the poll function is present
00141         // --> do it when necessary.
00142 
00143         // use an existing poll implementation
00144         int result = poll(fds, nfds, timeout);
00145         if ( result < 0 ) {
00146                 // EINTR means that we got interrupted by a signal, and is not an error
00147                 if(errno == EINTR) {
00148                         result = 0;
00149                 }
00150         }
00151         return result;
00152 #endif // poll_sockets functions
00153 }
00154 
00155 } // namespace ecl


ecl_io
Author(s): Daniel Stonier
autogenerated on Wed Aug 26 2015 11:27:18