$search
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