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.

113 lines
3.0 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 DEBUG
  24. #include <assert.h>
  25. #else
  26. #define assert(x)
  27. #endif
  28. /* IDEA: if someone calls io_dontwantwrite, do not do the syscall to
  29. * tell the kernel about it. Only when a write event comes in and the
  30. * user has told us he does not want them, THEN tell the kernel we are
  31. * not interested. In the typical protocol case of "write request, read
  32. * reply", this should save a lot of syscalls.
  33. * Now, if someone calls io_wantwrite, we might be in the situation that
  34. * canwrite is already set. In that case, just enqueue the fd. */
  35. void io_wantwrite_really(int64 d, io_entry* e) {
  36. int newfd;
  37. assert(!e->kernelwantwrite); /* we should not be here if we already told the kernel we want to write */
  38. newfd=(!e->kernelwantread);
  39. io_wanted_fds+=newfd;
  40. #ifdef HAVE_KQUEUE
  41. if (io_waitmode==KQUEUE) {
  42. struct kevent kev;
  43. struct timespec ts;
  44. EV_SET(&kev, d, EVFILT_WRITE, EV_ADD|EV_ENABLE, 0, 0, 0);
  45. ts.tv_sec=0; ts.tv_nsec=0;
  46. kevent(io_master,&kev,1,0,0,&ts);
  47. }
  48. #endif
  49. #ifdef HAVE_DEVPOLL
  50. if (io_waitmode==DEVPOLL) {
  51. struct pollfd x;
  52. x.fd=d;
  53. x.events=POLLOUT;
  54. if (e->wantread) x.events|=POLLIN;
  55. write(io_master,&x,sizeof(x));
  56. }
  57. #endif
  58. #if defined(HAVE_SIGIO) || defined(HAVE_EPOLL)
  59. if (io_waitmode==_SIGIO || io_waitmode==EPOLL) {
  60. struct pollfd p;
  61. if (io_waitmode==EPOLL && !e->epolladded) {
  62. struct epoll_event x;
  63. byte_zero(&x,sizeof(x)); // shut up valgrind
  64. x.events=EPOLLIN|EPOLLOUT|EPOLLET;
  65. x.data.fd=d;
  66. epoll_ctl(io_master,EPOLL_CTL_ADD,d,&x);
  67. e->epolladded=1;
  68. }
  69. if (e->canwrite==0) {
  70. p.fd=d;
  71. p.events=POLLOUT;
  72. switch (poll(&p,1,0)) {
  73. case 1: e->canwrite=1; break;
  74. // case 0: e->canwrite=0; break;
  75. case -1: return;
  76. }
  77. }
  78. if (e->canwrite) {
  79. debug_printf(("io_wantwrite: enqueueing %lld in normal write queue before %ld\n",d,first_readable));
  80. e->next_write=first_writeable;
  81. first_writeable=d;
  82. }
  83. }
  84. #endif
  85. #ifdef __MINGW32__
  86. printf("e->wantwrite == %d\n",e->wantwrite);
  87. if (!e->wantwrite) {
  88. e->next_write=first_writeable;
  89. e->canwrite=1;
  90. first_writeable=d;
  91. printf("queueing write, setting first_writeable to %lld\n",d);
  92. }
  93. #endif
  94. e->wantwrite=1;
  95. e->kernelwantwrite=1;
  96. }
  97. void io_wantwrite(int64 d) {
  98. io_entry* e=iarray_get(&io_fds,d);
  99. if (!e) return;
  100. if (e->wantwrite && e->kernelwantwrite) return;
  101. if (e->canwrite) {
  102. e->next_write=first_writeable;
  103. first_writeable=d;
  104. e->wantwrite=1;
  105. return;
  106. }
  107. /* the harder case: do as before */
  108. if (!e->kernelwantwrite) io_wantwrite_really(d, e); else e->wantwrite=1;
  109. }