fakepoll.c 2.6 KB

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