fakepoll.c 2.5 KB

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