Mirror of :pserver:anonymous@cvs.schmorp.de/schmorpforge libev http://software.schmorp.de/pkg/libev.html
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.

145 lines
4.0 KiB

  1. /*
  2. * Copyright 2007 Marc Alexander Lehmann <libev@schmorp.de>
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  15. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  17. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  18. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  19. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  20. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  21. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #include <sys/types.h>
  26. #include <sys/time.h>
  27. #include <poll.h>
  28. #include <port.h>
  29. #include <string.h>
  30. #include <errno.h>
  31. static void
  32. port_modify (EV_P_ int fd, int oev, int nev)
  33. {
  34. /* we need to reassociate no matter what, as closes are
  35. * once more silently being discarded.
  36. */
  37. if (!nev)
  38. {
  39. if (oev)
  40. port_dissociate (backend_fd, PORT_SOURCE_FD, fd);
  41. }
  42. else if (0 >
  43. port_associate (
  44. backend_fd, PORT_SOURCE_FD, fd,
  45. (nev & EV_READ ? POLLIN : 0)
  46. | (nev & EV_WRITE ? POLLOUT : 0),
  47. 0
  48. )
  49. )
  50. {
  51. if (errno == EBADFD)
  52. fd_kill (EV_A_ fd);
  53. else
  54. syserr ("(libev) port_associate");
  55. }
  56. }
  57. static void
  58. port_poll (EV_P_ ev_tstamp timeout)
  59. {
  60. int res, i;
  61. struct timespec ts;
  62. uint_t nget = 1;
  63. ts.tv_sec = (time_t)timeout;
  64. ts.tv_nsec = (long)(timeout - (ev_tstamp)ts.tv_sec) * 1e9;
  65. res = port_getn (backend_fd, port_events, port_eventmax, &nget, &ts);
  66. if (res < 0)
  67. {
  68. if (errno != EINTR && errno != ETIME)
  69. syserr ("(libev) port_getn");
  70. return;
  71. }
  72. for (i = 0; i < nget; ++i)
  73. {
  74. if (port_events [i].portev_source == PORT_SOURCE_FD)
  75. {
  76. int fd = port_events [i].portev_object;
  77. fd_event (
  78. EV_A_
  79. fd,
  80. (port_events [i].portev_events & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0)
  81. | (port_events [i].portev_events & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0)
  82. );
  83. anfds [fd].events = 0; /* event received == disassociated */
  84. fd_change (EV_A_ fd); /* need to reify later */
  85. }
  86. }
  87. if (expect_false (nget == port_eventmax))
  88. {
  89. ev_free (port_events);
  90. port_eventmax = array_roundsize (port_event_t, port_eventmax << 1);
  91. port_events = (port_event_t *)ev_malloc (sizeof (port_event_t) * port_eventmax);
  92. }
  93. }
  94. static int
  95. port_init (EV_P_ int flags)
  96. {
  97. /* Initalize the kernel queue */
  98. if ((backend_fd = port_create ()) < 0)
  99. return 0;
  100. fcntl (backend_fd, F_SETFD, FD_CLOEXEC); /* not sure if necessary, hopefully doesn't hurt */
  101. backend_fudge = 1e-3; /* needed to compensate for port_getn returning early */
  102. backend_modify = port_modify;
  103. backend_poll = port_poll;
  104. port_eventmax = 64; /* intiial number of events receivable per poll */
  105. port_events = (port_event_t *)ev_malloc (sizeof (port_event_t) * port_eventmax);
  106. return EVBACKEND_PORT;
  107. }
  108. static void
  109. port_destroy (EV_P)
  110. {
  111. close (backend_fd);
  112. ev_free (port_events);
  113. }
  114. static void
  115. port_fork (EV_P)
  116. {
  117. close (backend_fd);
  118. while ((backend_fd = port_create ()) < 0)
  119. syserr ("(libev) port");
  120. fcntl (backend_fd, F_SETFD, FD_CLOEXEC);
  121. /* re-register interest in fds */
  122. fd_rearm_all (EV_A);
  123. }