fakepoll.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /* Copyright 2002,2003 Nick Mathewson, Roger Dingledine */
  2. /* See LICENSE for licensing information */
  3. /* $Id$ */
  4. /*****
  5. * fakepoll.c: On systems where 'poll' doesn't exist, fake it with 'select'.
  6. *****/
  7. #include "orconfig.h"
  8. #include "fakepoll.h"
  9. #ifdef USE_FAKE_POLL
  10. #include <sys/types.h>
  11. #ifdef HAVE_UNISTD_H
  12. #include <unistd.h>
  13. #endif
  14. #ifdef HAVE_STRING_H
  15. #include <string.h>
  16. #endif
  17. #ifdef HAVE_SYS_TIME_H
  18. #include <sys/time.h>
  19. #endif
  20. #if _MSC_VER > 1300
  21. #include <winsock2.h>
  22. #include <ws2tcpip.h>
  23. #elif defined(_MSC_VER)
  24. #include <winsock.h>
  25. #endif
  26. /* by default, windows handles only 64 fd's */
  27. #if defined(MS_WINDOWS) && !defined(FD_SETSIZE)
  28. #define FD_SETSIZE MAXCONNECTIONS
  29. #endif
  30. #include "util.h"
  31. int
  32. tor_poll(struct pollfd *ufds, unsigned int nfds, int timeout)
  33. {
  34. unsigned int idx;
  35. int maxfd, fd;
  36. int r;
  37. #ifdef MS_WINDOWS
  38. int any_fds_set = 0;
  39. #endif
  40. fd_set readfds, writefds, exceptfds;
  41. #ifdef USING_FAKE_TIMEVAL
  42. #undef timeval
  43. #undef tv_sec
  44. #undef tv_usec
  45. #endif
  46. struct timeval _timeout;
  47. _timeout.tv_sec = timeout/1000;
  48. _timeout.tv_usec = (timeout%1000)*1000;
  49. FD_ZERO(&readfds);
  50. FD_ZERO(&writefds);
  51. FD_ZERO(&exceptfds);
  52. maxfd = -1;
  53. for (idx = 0; idx < nfds; ++idx) {
  54. ufds[idx].revents = 0;
  55. fd = ufds[idx].fd;
  56. tor_assert(fd >= 0);
  57. if (fd > maxfd) {
  58. maxfd = fd;
  59. #ifdef MS_WINDOWS
  60. any_fds_set = 1;
  61. #endif
  62. }
  63. if (ufds[idx].events & POLLIN)
  64. FD_SET(fd, &readfds);
  65. if (ufds[idx].events & POLLOUT)
  66. FD_SET(fd, &writefds);
  67. FD_SET(fd, &exceptfds);
  68. }
  69. #ifdef MS_WINDOWS
  70. if (!any_fds_set) {
  71. Sleep(timeout);
  72. return 0;
  73. }
  74. #endif
  75. r = select(maxfd+1, &readfds, &writefds, &exceptfds,
  76. timeout == -1 ? NULL : &_timeout);
  77. if (r <= 0)
  78. return r;
  79. r = 0;
  80. for (idx = 0; idx < nfds; ++idx) {
  81. fd = ufds[idx].fd;
  82. if (FD_ISSET(fd, &readfds))
  83. ufds[idx].revents |= POLLIN;
  84. if (FD_ISSET(fd, &writefds))
  85. ufds[idx].revents |= POLLOUT;
  86. if (FD_ISSET(fd, &exceptfds))
  87. ufds[idx].revents |= POLLERR;
  88. if (ufds[idx].revents)
  89. ++r;
  90. }
  91. return r;
  92. }
  93. #endif
  94. /*
  95. Local Variables:
  96. mode:c
  97. indent-tabs-mode:nil
  98. c-basic-offset:2
  99. End:
  100. */