jack1 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

166 lines
3.8KB

  1. // fakepoll.h
  2. // poll using select
  3. // Warning: a call to this poll() takes about 4K of stack space.
  4. // Greg Parker gparker-web@sealiesoftware.com December 2000
  5. // This code is in the public domain and may be copied or modified without
  6. // permission.
  7. // Updated May 2002:
  8. // * fix crash when an fd is less than 0
  9. // * set errno=EINVAL if an fd is greater or equal to FD_SETSIZE
  10. // * don't set POLLIN or POLLOUT in revents if it wasn't requested
  11. // in events (only happens when an fd is in the poll set twice)
  12. #ifndef _FAKE_POLL_H
  13. #define _FAKE_POLL_H
  14. #include <limits.h>
  15. #include <sys/types.h>
  16. #include <sys/time.h>
  17. #include <unistd.h>
  18. #include <stdlib.h>
  19. #include <errno.h>
  20. typedef struct pollfd {
  21. int fd; /* file desc to poll */
  22. short events; /* events of interest on fd */
  23. short revents; /* events that occurred on fd */
  24. } pollfd_t;
  25. // poll flags
  26. #define POLLIN 0x0001
  27. #define POLLOUT 0x0004
  28. #define POLLERR 0x0008
  29. // synonyms
  30. #define POLLNORM POLLIN
  31. #define POLLPRI POLLIN
  32. #define POLLRDNORM POLLIN
  33. #define POLLRDBAND POLLIN
  34. #define POLLWRNORM POLLOUT
  35. #define POLLWRBAND POLLOUT
  36. // ignored
  37. #define POLLHUP 0x0010
  38. #define POLLNVAL 0x0020
  39. static inline int
  40. poll (struct pollfd *pollSet, int pollCount, int pollTimeout)
  41. {
  42. struct timeval tv;
  43. struct timeval *tvp;
  44. fd_set readFDs, writeFDs, exceptFDs;
  45. fd_set *readp, *writep, *exceptp;
  46. struct pollfd *pollEnd, *p;
  47. int selected;
  48. int result;
  49. int maxFD;
  50. if (!pollSet) {
  51. pollEnd = NULL;
  52. readp = NULL;
  53. writep = NULL;
  54. exceptp = NULL;
  55. maxFD = 0;
  56. } else {
  57. pollEnd = pollSet + pollCount;
  58. readp = &readFDs;
  59. writep = &writeFDs;
  60. exceptp = &exceptFDs;
  61. FD_ZERO (readp);
  62. FD_ZERO (writep);
  63. FD_ZERO (exceptp);
  64. // Find the biggest fd in the poll set
  65. maxFD = 0;
  66. for (p = pollSet; p < pollEnd; p++)
  67. if (p->fd > maxFD) {
  68. maxFD = p->fd;
  69. }
  70. if (maxFD >= FD_SETSIZE) {
  71. // At least one fd is too big
  72. errno = EINVAL;
  73. return -1;
  74. }
  75. // Transcribe flags from the poll set to the fd sets
  76. for (p = pollSet; p < pollEnd; p++) {
  77. if (p->fd < 0) {
  78. // Negative fd checks nothing and always reports zero
  79. } else {
  80. if (p->events & POLLIN) {
  81. FD_SET (p->fd, readp);
  82. }
  83. if (p->events & POLLOUT) {
  84. FD_SET (p->fd, writep);
  85. }
  86. if (p->events != 0) {
  87. FD_SET (p->fd, exceptp);
  88. }
  89. // POLLERR is never set coming in; poll() always reports errors
  90. // But don't report if we're not listening to anything at all.
  91. }
  92. }
  93. }
  94. // poll timeout is in milliseconds. Convert to struct timeval.
  95. // poll timeout == -1 : wait forever : select timeout of NULL
  96. // poll timeout == 0 : return immediately : select timeout of zero
  97. if (pollTimeout >= 0) {
  98. tv.tv_sec = pollTimeout / 1000;
  99. tv.tv_usec = (pollTimeout % 1000) * 1000;
  100. tvp = &tv;
  101. } else {
  102. tvp = NULL;
  103. }
  104. selected = select (maxFD + 1, readp, writep, exceptp, tvp);
  105. if (selected < 0) {
  106. // Error during select
  107. result = -1;
  108. } else if (selected > 0) {
  109. // Select found something
  110. // Transcribe result from fd sets to poll set.
  111. // Also count the number of selected fds. poll returns the
  112. // number of ready fds; select returns the number of bits set.
  113. int polled = 0;
  114. for (p = pollSet; p < pollEnd; p++) {
  115. p->revents = 0;
  116. if (p->fd < 0) {
  117. // Negative fd always reports zero
  118. } else {
  119. if ((p->events & POLLIN) && FD_ISSET (p->fd, readp)) {
  120. p->revents |= POLLIN;
  121. }
  122. if ((p->events & POLLOUT) && FD_ISSET (p->fd, writep)) {
  123. p->revents |= POLLOUT;
  124. }
  125. if ((p->events != 0) && FD_ISSET (p->fd, exceptp)) {
  126. p->revents |= POLLERR;
  127. }
  128. if (p->revents) {
  129. polled++;
  130. }
  131. }
  132. }
  133. result = polled;
  134. } else {
  135. // selected == 0, select timed out before anything happened
  136. // Clear all result bits and return zero.
  137. for (p = pollSet; p < pollEnd; p++)
  138. p->revents = 0;
  139. result = 0;
  140. }
  141. return result;
  142. }
  143. #endif