lib/poll.cpp
Go to the documentation of this file.
1 
9 /*****************************************************************************
10 ** Includes
11 *****************************************************************************/
12 
13 #include "../../include/ecl/io/poll.hpp"
14 
15 /*****************************************************************************
16 ** Namespaces
17 *****************************************************************************/
18 
19 namespace ecl {
20 
21 /*****************************************************************************
22 ** Implementation
23 *****************************************************************************/
24 
25 int poll_sockets(socket_pollfd *fds, nfds_t nfds, int timeout) {
26 #if defined(ECL_IS_WIN32)
27  fd_set readfds, writefds, exceptfds;
28  struct timeval tv, *ptv;
29  socket_descriptor max_fd;
30  int rc;
31  nfds_t i;
32 
33  if (fds == NULL) {
34  errno = EFAULT;
35  return -1;
36  }
37 
38  FD_ZERO (&readfds);
39  FD_ZERO (&writefds);
40  FD_ZERO (&exceptfds);
41 
42  /*********************
43  ** Compute fd sets
44  **********************/
45  // also find the largest descriptor.
46  for (rc = -1, max_fd = 0, i = 0; i < nfds; i++) {
47  if (fds[i].fd == INVALID_SOCKET) {
48  continue;
49  }
50  if (fds[i].events & (POLLIN | POLLRDNORM)) {
51  FD_SET (fds[i].fd, &readfds);
52  }
53  if (fds[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND)) {
54  FD_SET (fds[i].fd, &writefds);
55  }
56  if (fds[i].events & (POLLPRI | POLLRDBAND)) {
57  FD_SET (fds[i].fd, &exceptfds);
58  }
59  if (fds[i].fd > max_fd &&
60  (fds[i].events & (POLLIN | POLLOUT | POLLPRI |
61  POLLRDNORM | POLLRDBAND |
62  POLLWRNORM | POLLWRBAND))) {
63  max_fd = fds[i].fd;
64  rc = 0;
65  }
66  }
67 
68  if (rc == -1) {
69  errno = EINVAL;
70  return -1;
71  }
72  /*********************
73  ** Setting the timeout
74  **********************/
75  if (timeout < 0) {
76  ptv = NULL;
77  } else {
78  ptv = &tv;
79  if (timeout == 0) {
80  tv.tv_sec = 0;
81  tv.tv_usec = 0;
82  } else {
83  tv.tv_sec = timeout / 1000;
84  tv.tv_usec = (timeout % 1000) * 1000;
85  }
86  }
87 
88  rc = select (max_fd + 1, &readfds, &writefds, &exceptfds, ptv);
89  if (rc < 0) {
90  return -1;
91  } else if ( rc == 0 ) {
92  return 0;
93  }
94 
95  for (rc = 0, i = 0; i < nfds; i++) {
96  if (fds[i].fd != INVALID_SOCKET) {
97  fds[i].revents = 0;
98 
99  if (FD_ISSET(fds[i].fd, &readfds)) {
100  int save_errno = errno;
101  char data[64] = {0};
102  int ret;
103 
104  /* support for POLLHUP */
105  // just check if there's incoming data, without removing it from the queue.
106  ret = recv(fds[i].fd, data, 64, MSG_PEEK);
107  #ifdef WIN32
108  if ((ret == -1) &&
109  (errno == WSAESHUTDOWN || errno == WSAECONNRESET ||
110  (errno == WSAECONNABORTED) || errno == WSAENETRESET))
111  #else
112  if ((ret == -1) &&
113  (errno == ESHUTDOWN || errno == ECONNRESET ||
114  (errno == ECONNABORTED) || errno == ENETRESET))
115  #endif
116  {
117  fds[i].revents |= POLLHUP;
118  } else {
119  fds[i].revents |= fds[i].events & (POLLIN | POLLRDNORM);
120  }
121  errno = save_errno;
122  }
123  if (FD_ISSET(fds[i].fd, &writefds)) {
124  fds[i].revents |= fds[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND);
125  }
126 
127  if (FD_ISSET(fds[i].fd, &exceptfds)) {
128  fds[i].revents |= fds[i].events & (POLLPRI | POLLRDBAND);
129  }
130 
131  if (fds[i].revents & ~POLLHUP) {
132  rc++;
133  }
134  } else {
135  fds[i].revents = POLLNVAL;
136  }
137  }
138  return rc;
139 #else
140  // should really put in a cmake check to check that the poll function is present
141  // --> do it when necessary.
142 
143  // use an existing poll implementation
144  int result = poll(fds, nfds, timeout);
145  if ( result < 0 ) {
146  // EINTR means that we got interrupted by a signal, and is not an error
147  if(errno == EINTR) {
148  result = 0;
149  }
150  }
151  return result;
152 #endif // poll_sockets functions
153 }
154 
155 } // namespace ecl
int socket_descriptor
Cross-platform typedef for a socket file descriptor.
Definition: sockets.hpp:58
struct pollfd socket_pollfd
Definition: poll.hpp:87
ecl_io_PUBLIC int poll_sockets(socket_pollfd *fds, nfds_t nfds, int timeout)
Definition: lib/poll.cpp:25


ecl_io
Author(s): Daniel Stonier
autogenerated on Mon Feb 28 2022 22:16:11