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.
 
 
 
 

140 lines
3.7 KiB

  1. #ifndef my_extern
  2. #define my_extern extern
  3. #endif
  4. #include "libowfat/io.h"
  5. #include "libowfat/array.h"
  6. #include "libowfat/iarray.h"
  7. #ifdef __MINGW32__
  8. #include "socket.h"
  9. my_extern HANDLE io_comport;
  10. #else
  11. #include "haveepoll.h"
  12. #include "havekqueue.h"
  13. #include "havedevpoll.h"
  14. #include "havesigio.h"
  15. #ifdef HAVE_SIGIO
  16. #define _GNU_SOURCE
  17. #include <signal.h>
  18. #endif
  19. #endif
  20. /* We simulate a level-triggered API on top of an event signalling
  21. * mechanism that can be level-triggered (epoll/kqueue/poll) or
  22. * edge-triggered (SIGIO).
  23. * Difficulty: we want to avoid unnecessary syscalls, so we keep state
  24. * internally. If the user says he does not want to read/write anymore,
  25. * we don't tell the kernel straight away. The rationale is that the
  26. * typical protocol consists of interleaved reading and writing, so
  27. * after each read you'd call io_dontwantread, io_wantwrite, io_wait,
  28. * io_dontwantwrite, io_wantread, and in the regular case there is no
  29. * incoming data between io_dontwantread and io_wantread, so we might as
  30. * well optimistically not do those syscalls and then handle the
  31. * complexity if there is more incoming data. */
  32. /* Basically, we tell the kernel that we want to read if !canread,
  33. * and we tell the kernel that we want to write if !canwrite. */
  34. typedef struct {
  35. tai6464 timeout;
  36. unsigned int wantread:1; /* does the app want to read/write? */
  37. unsigned int wantwrite:1;
  38. unsigned int canread:1; /* do we know we can read/write? */
  39. unsigned int canwrite:1;
  40. unsigned int nonblock:1; /* is this socket non-blocking? */
  41. unsigned int inuse:1; /* internal consistency checking */
  42. unsigned int kernelwantread:1; /* did we tell the kernel we want to read/write? */
  43. unsigned int kernelwantwrite:1;
  44. unsigned int epolladded:1;
  45. unsigned int closed:1; /* io_close called, but close deferred because of outstanding events */
  46. unsigned int zerocopy:1; /* linux: setsockopt SO_ZEROCOPY done */
  47. #ifdef __MINGW32__
  48. unsigned int readqueued:2;
  49. unsigned int writequeued:2;
  50. unsigned int acceptqueued:2;
  51. unsigned int connectqueued:2;
  52. unsigned int sendfilequeued:2;
  53. unsigned int listened:1;
  54. #endif
  55. long next_read;
  56. long next_write;
  57. long next_defer;
  58. void* cookie;
  59. void* mmapped;
  60. long maplen;
  61. uint64 mapofs;
  62. #ifdef __MINGW32__
  63. OVERLAPPED or,ow,os; /* overlapped for read+accept, write+connect, sendfile */
  64. HANDLE /* fd, */ mh;
  65. char inbuf[8192];
  66. int bytes_read,bytes_written;
  67. DWORD errorcode;
  68. SOCKET next_accept;
  69. #endif
  70. } io_entry;
  71. extern int io_multithreaded;
  72. extern int io_sockets[2];
  73. my_extern iarray io_fds;
  74. my_extern uint64 io_wanted_fds;
  75. my_extern array io_pollfds;
  76. my_extern long first_readable;
  77. my_extern long first_writeable;
  78. extern long first_deferred;
  79. my_extern enum __io_waitmode {
  80. UNDECIDED,
  81. POLL
  82. #ifdef HAVE_KQUEUE
  83. ,KQUEUE
  84. #endif
  85. #ifdef HAVE_EPOLL
  86. ,EPOLL
  87. #endif
  88. #ifdef HAVE_SIGIO
  89. ,_SIGIO
  90. #endif
  91. #ifdef HAVE_DEVPOLL
  92. ,DEVPOLL
  93. #endif
  94. #ifdef __MINGW32__
  95. ,COMPLETIONPORT
  96. #endif
  97. } io_waitmode;
  98. #if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL) || defined(HAVE_DEVPOLL)
  99. my_extern int io_master;
  100. #endif
  101. #if defined(HAVE_SIGIO)
  102. my_extern int io_signum;
  103. my_extern sigset_t io_ss;
  104. my_extern long alt_firstread, alt_firstwrite;
  105. my_extern long alt_curread, alt_curwrite;
  106. #endif
  107. int64 io_waituntil2(int64 milliseconds);
  108. void io_sigpipe(void);
  109. /* return next descriptor from io_wait that can be read from */
  110. int64 io_canread_unlocked();
  111. /* return next descriptor from io_wait that can be written to */
  112. int64 io_canwrite_unlocked();
  113. /* return next descriptor with expired timeout */
  114. int64 io_timeouted_unlocked();
  115. struct eventpacket {
  116. int fd;
  117. enum { CANREAD, CANWRITE, TIMEOUT } what;
  118. };
  119. #define debug_printf(x)
  120. struct iom_entry {
  121. void* cookie;
  122. };