Mirror of :pserver:cvs@cvs.fefe.de:/cvs libowfat https://www.fefe.de/libowfat/
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.

126 lines
2.9 KiB

18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
18 years ago
  1. #include <unistd.h>
  2. #include <fcntl.h>
  3. #include <errno.h>
  4. #include "io_internal.h"
  5. #ifdef HAVE_KQUEUE
  6. #include <sys/types.h>
  7. #include <sys/event.h>
  8. #include <sys/time.h>
  9. #endif
  10. #ifdef HAVE_EPOLL
  11. #include <inttypes.h>
  12. #include <sys/epoll.h>
  13. #include <byte.h>
  14. #endif
  15. #ifdef HAVE_SIGIO
  16. #include <sys/poll.h>
  17. #endif
  18. #ifdef HAVE_DEVPOLL
  19. #include <sys/types.h>
  20. #include <sys/socket.h>
  21. #include <sys/devpoll.h>
  22. #endif
  23. #ifdef __MINGW32__
  24. #include <mswsock.h>
  25. #endif
  26. #ifdef DEBUG
  27. #include <assert.h>
  28. #else
  29. #define assert(x)
  30. #endif
  31. void io_wantread_really(int64 d,io_entry* e) {
  32. int newfd;
  33. assert(!e->kernelwantread);
  34. newfd=!e->kernelwantwrite;
  35. io_wanted_fds+=newfd;
  36. #ifdef HAVE_KQUEUE
  37. if (io_waitmode==KQUEUE) {
  38. struct kevent kev;
  39. struct timespec ts;
  40. EV_SET(&kev, d, EVFILT_READ, EV_ADD|EV_ENABLE, 0, 0, 0);
  41. ts.tv_sec=0; ts.tv_nsec=0;
  42. kevent(io_master,&kev,1,0,0,&ts);
  43. }
  44. #endif
  45. #ifdef HAVE_DEVPOLL
  46. if (io_waitmode==DEVPOLL) {
  47. struct pollfd x;
  48. x.fd=d;
  49. x.events=POLLIN;
  50. if (e->wantwrite) x.events|=POLLOUT;
  51. write(io_master,&x,sizeof(x));
  52. }
  53. #endif
  54. #if defined(HAVE_SIGIO) || defined(HAVE_EPOLL)
  55. if (io_waitmode==_SIGIO || io_waitmode==EPOLL) {
  56. struct pollfd p;
  57. if (io_waitmode==EPOLL && !e->epolladded) {
  58. struct epoll_event x;
  59. byte_zero(&x,sizeof(x)); // shut up valgrind
  60. x.events=EPOLLIN|EPOLLOUT|EPOLLET;
  61. x.data.fd=d;
  62. epoll_ctl(io_master,EPOLL_CTL_ADD,d,&x);
  63. e->epolladded=1;
  64. }
  65. if (e->canread==0) {
  66. p.fd=d;
  67. p.events=POLLIN;
  68. switch (poll(&p,1,0)) {
  69. case 1: e->canread=1; break;
  70. // case 0: e->canread=0; break;
  71. case -1: return;
  72. }
  73. }
  74. if (e->canread) {
  75. debug_printf(("io_wantread: enqueueing %lld in normal read queue (next is %ld)\n",d,first_readable));
  76. e->next_read=first_readable;
  77. first_readable=d;
  78. }
  79. }
  80. #endif
  81. #ifdef __MINGW32__
  82. if (e->listened) {
  83. if (e->next_accept==0) e->next_accept=socket(AF_INET,SOCK_STREAM,0);
  84. if (e->next_accept!=-1) {
  85. AcceptEx(d,e->next_accept,e->inbuf,0,200,200,&e->errorcode,&e->or);
  86. e->acceptqueued=1;
  87. }
  88. } else if (!e->wantread) {
  89. if (ReadFile((HANDLE)d,e->inbuf,sizeof(e->inbuf),&e->errorcode,&e->or)) {
  90. queueread:
  91. /* had something to read immediately. Damn! */
  92. e->readqueued=0;
  93. e->canread=1;
  94. e->bytes_read=e->errorcode;
  95. e->errorcode=0;
  96. e->next_read=first_readable;
  97. first_readable=d;
  98. return;
  99. } else if (GetLastError()==ERROR_IO_PENDING)
  100. e->readqueued=1;
  101. else
  102. goto queueread;
  103. #if 0
  104. e->next_read=first_readable;
  105. first_readable=d;
  106. #endif
  107. }
  108. #endif
  109. e->wantread=1;
  110. e->kernelwantread=1;
  111. }
  112. void io_wantread(int64 d) {
  113. io_entry* e=iarray_get(&io_fds,d);
  114. if (!e || e->wantread) return;
  115. if (e->canread) {
  116. e->next_read=first_readable;
  117. first_readable=d;
  118. e->wantread=1;
  119. return;
  120. }
  121. /* the harder case: do as before */
  122. if (!e->kernelwantread) io_wantread_really(d, e); else e->wantread=1;
  123. }