rbuv 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (233) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +0 -1
  6. data/README.md +6 -1
  7. data/Rakefile +42 -0
  8. data/deps/libuv/.gitignore +34 -0
  9. data/deps/libuv/.mailmap +16 -0
  10. data/deps/libuv/AUTHORS +81 -0
  11. data/deps/libuv/ChangeLog +45 -0
  12. data/deps/libuv/LICENSE +41 -0
  13. data/deps/libuv/Makefile +53 -0
  14. data/deps/libuv/README.md +118 -0
  15. data/deps/libuv/build.mk +164 -0
  16. data/deps/libuv/checksparse.sh +230 -0
  17. data/deps/libuv/common.gypi +197 -0
  18. data/deps/libuv/config-mingw.mk +48 -0
  19. data/deps/libuv/config-unix.mk +167 -0
  20. data/deps/libuv/gyp_uv +98 -0
  21. data/deps/libuv/include/uv-private/ngx-queue.h +129 -0
  22. data/deps/libuv/include/uv-private/stdint-msvc2008.h +247 -0
  23. data/deps/libuv/include/uv-private/tree.h +768 -0
  24. data/deps/libuv/include/uv-private/uv-bsd.h +34 -0
  25. data/deps/libuv/include/uv-private/uv-darwin.h +61 -0
  26. data/deps/libuv/include/uv-private/uv-linux.h +34 -0
  27. data/deps/libuv/include/uv-private/uv-sunos.h +44 -0
  28. data/deps/libuv/include/uv-private/uv-unix.h +332 -0
  29. data/deps/libuv/include/uv-private/uv-win.h +585 -0
  30. data/deps/libuv/include/uv.h +1987 -0
  31. data/deps/libuv/src/fs-poll.c +248 -0
  32. data/deps/libuv/src/inet.c +298 -0
  33. data/deps/libuv/src/unix/aix.c +393 -0
  34. data/deps/libuv/src/unix/async.c +281 -0
  35. data/deps/libuv/src/unix/core.c +714 -0
  36. data/deps/libuv/src/unix/cygwin.c +93 -0
  37. data/deps/libuv/src/unix/darwin-proctitle.m +78 -0
  38. data/deps/libuv/src/unix/darwin.c +431 -0
  39. data/deps/libuv/src/unix/dl.c +83 -0
  40. data/deps/libuv/src/unix/error.c +109 -0
  41. data/deps/libuv/src/unix/freebsd.c +343 -0
  42. data/deps/libuv/src/unix/fs.c +869 -0
  43. data/deps/libuv/src/unix/fsevents.c +299 -0
  44. data/deps/libuv/src/unix/getaddrinfo.c +159 -0
  45. data/deps/libuv/src/unix/internal.h +259 -0
  46. data/deps/libuv/src/unix/kqueue.c +347 -0
  47. data/deps/libuv/src/unix/linux-core.c +724 -0
  48. data/deps/libuv/src/unix/linux-inotify.c +236 -0
  49. data/deps/libuv/src/unix/linux-syscalls.c +388 -0
  50. data/deps/libuv/src/unix/linux-syscalls.h +150 -0
  51. data/deps/libuv/src/unix/loop-watcher.c +64 -0
  52. data/deps/libuv/src/unix/loop.c +114 -0
  53. data/deps/libuv/src/unix/netbsd.c +353 -0
  54. data/deps/libuv/src/unix/openbsd.c +304 -0
  55. data/deps/libuv/src/unix/pipe.c +261 -0
  56. data/deps/libuv/src/unix/poll.c +108 -0
  57. data/deps/libuv/src/unix/process.c +501 -0
  58. data/deps/libuv/src/unix/proctitle.c +103 -0
  59. data/deps/libuv/src/unix/signal.c +455 -0
  60. data/deps/libuv/src/unix/stream.c +1380 -0
  61. data/deps/libuv/src/unix/sunos.c +647 -0
  62. data/deps/libuv/src/unix/tcp.c +357 -0
  63. data/deps/libuv/src/unix/thread.c +431 -0
  64. data/deps/libuv/src/unix/threadpool.c +286 -0
  65. data/deps/libuv/src/unix/timer.c +153 -0
  66. data/deps/libuv/src/unix/tty.c +179 -0
  67. data/deps/libuv/src/unix/udp.c +715 -0
  68. data/deps/libuv/src/uv-common.c +431 -0
  69. data/deps/libuv/src/uv-common.h +204 -0
  70. data/deps/libuv/src/version.c +60 -0
  71. data/deps/libuv/src/win/async.c +99 -0
  72. data/deps/libuv/src/win/atomicops-inl.h +56 -0
  73. data/deps/libuv/src/win/core.c +310 -0
  74. data/deps/libuv/src/win/dl.c +86 -0
  75. data/deps/libuv/src/win/error.c +164 -0
  76. data/deps/libuv/src/win/fs-event.c +506 -0
  77. data/deps/libuv/src/win/fs.c +1951 -0
  78. data/deps/libuv/src/win/getaddrinfo.c +365 -0
  79. data/deps/libuv/src/win/handle-inl.h +164 -0
  80. data/deps/libuv/src/win/handle.c +153 -0
  81. data/deps/libuv/src/win/internal.h +346 -0
  82. data/deps/libuv/src/win/loop-watcher.c +124 -0
  83. data/deps/libuv/src/win/pipe.c +1656 -0
  84. data/deps/libuv/src/win/poll.c +615 -0
  85. data/deps/libuv/src/win/process-stdio.c +503 -0
  86. data/deps/libuv/src/win/process.c +1048 -0
  87. data/deps/libuv/src/win/req-inl.h +224 -0
  88. data/deps/libuv/src/win/req.c +25 -0
  89. data/deps/libuv/src/win/signal.c +354 -0
  90. data/deps/libuv/src/win/stream-inl.h +67 -0
  91. data/deps/libuv/src/win/stream.c +198 -0
  92. data/deps/libuv/src/win/tcp.c +1422 -0
  93. data/deps/libuv/src/win/thread.c +666 -0
  94. data/deps/libuv/src/win/threadpool.c +82 -0
  95. data/deps/libuv/src/win/timer.c +230 -0
  96. data/deps/libuv/src/win/tty.c +1857 -0
  97. data/deps/libuv/src/win/udp.c +744 -0
  98. data/deps/libuv/src/win/util.c +946 -0
  99. data/deps/libuv/src/win/winapi.c +152 -0
  100. data/deps/libuv/src/win/winapi.h +4476 -0
  101. data/deps/libuv/src/win/winsock.c +560 -0
  102. data/deps/libuv/src/win/winsock.h +171 -0
  103. data/deps/libuv/test/benchmark-async-pummel.c +119 -0
  104. data/deps/libuv/test/benchmark-async.c +139 -0
  105. data/deps/libuv/test/benchmark-fs-stat.c +136 -0
  106. data/deps/libuv/test/benchmark-getaddrinfo.c +91 -0
  107. data/deps/libuv/test/benchmark-list.h +163 -0
  108. data/deps/libuv/test/benchmark-loop-count.c +90 -0
  109. data/deps/libuv/test/benchmark-million-async.c +112 -0
  110. data/deps/libuv/test/benchmark-million-timers.c +77 -0
  111. data/deps/libuv/test/benchmark-multi-accept.c +432 -0
  112. data/deps/libuv/test/benchmark-ping-pongs.c +212 -0
  113. data/deps/libuv/test/benchmark-pound.c +325 -0
  114. data/deps/libuv/test/benchmark-pump.c +459 -0
  115. data/deps/libuv/test/benchmark-sizes.c +45 -0
  116. data/deps/libuv/test/benchmark-spawn.c +163 -0
  117. data/deps/libuv/test/benchmark-tcp-write-batch.c +141 -0
  118. data/deps/libuv/test/benchmark-thread.c +64 -0
  119. data/deps/libuv/test/benchmark-udp-pummel.c +238 -0
  120. data/deps/libuv/test/blackhole-server.c +118 -0
  121. data/deps/libuv/test/dns-server.c +329 -0
  122. data/deps/libuv/test/echo-server.c +384 -0
  123. data/deps/libuv/test/fixtures/empty_file +0 -0
  124. data/deps/libuv/test/fixtures/load_error.node +1 -0
  125. data/deps/libuv/test/run-benchmarks.c +64 -0
  126. data/deps/libuv/test/run-tests.c +159 -0
  127. data/deps/libuv/test/runner-unix.c +328 -0
  128. data/deps/libuv/test/runner-unix.h +36 -0
  129. data/deps/libuv/test/runner-win.c +318 -0
  130. data/deps/libuv/test/runner-win.h +43 -0
  131. data/deps/libuv/test/runner.c +394 -0
  132. data/deps/libuv/test/runner.h +165 -0
  133. data/deps/libuv/test/task.h +122 -0
  134. data/deps/libuv/test/test-active.c +83 -0
  135. data/deps/libuv/test/test-async.c +136 -0
  136. data/deps/libuv/test/test-barrier.c +98 -0
  137. data/deps/libuv/test/test-callback-order.c +77 -0
  138. data/deps/libuv/test/test-callback-stack.c +204 -0
  139. data/deps/libuv/test/test-condvar.c +173 -0
  140. data/deps/libuv/test/test-connection-fail.c +150 -0
  141. data/deps/libuv/test/test-cwd-and-chdir.c +64 -0
  142. data/deps/libuv/test/test-delayed-accept.c +189 -0
  143. data/deps/libuv/test/test-dlerror.c +58 -0
  144. data/deps/libuv/test/test-embed.c +136 -0
  145. data/deps/libuv/test/test-error.c +59 -0
  146. data/deps/libuv/test/test-fail-always.c +29 -0
  147. data/deps/libuv/test/test-fs-event.c +504 -0
  148. data/deps/libuv/test/test-fs-poll.c +148 -0
  149. data/deps/libuv/test/test-fs.c +1899 -0
  150. data/deps/libuv/test/test-get-currentexe.c +63 -0
  151. data/deps/libuv/test/test-get-loadavg.c +36 -0
  152. data/deps/libuv/test/test-get-memory.c +38 -0
  153. data/deps/libuv/test/test-getaddrinfo.c +120 -0
  154. data/deps/libuv/test/test-getsockname.c +344 -0
  155. data/deps/libuv/test/test-hrtime.c +54 -0
  156. data/deps/libuv/test/test-idle.c +82 -0
  157. data/deps/libuv/test/test-ipc-send-recv.c +218 -0
  158. data/deps/libuv/test/test-ipc.c +625 -0
  159. data/deps/libuv/test/test-list.h +492 -0
  160. data/deps/libuv/test/test-loop-handles.c +337 -0
  161. data/deps/libuv/test/test-loop-stop.c +73 -0
  162. data/deps/libuv/test/test-multiple-listen.c +103 -0
  163. data/deps/libuv/test/test-mutexes.c +63 -0
  164. data/deps/libuv/test/test-pass-always.c +28 -0
  165. data/deps/libuv/test/test-ping-pong.c +250 -0
  166. data/deps/libuv/test/test-pipe-bind-error.c +144 -0
  167. data/deps/libuv/test/test-pipe-connect-error.c +98 -0
  168. data/deps/libuv/test/test-platform-output.c +87 -0
  169. data/deps/libuv/test/test-poll-close.c +73 -0
  170. data/deps/libuv/test/test-poll.c +575 -0
  171. data/deps/libuv/test/test-process-title.c +49 -0
  172. data/deps/libuv/test/test-ref.c +415 -0
  173. data/deps/libuv/test/test-run-nowait.c +46 -0
  174. data/deps/libuv/test/test-run-once.c +49 -0
  175. data/deps/libuv/test/test-semaphore.c +111 -0
  176. data/deps/libuv/test/test-shutdown-close.c +105 -0
  177. data/deps/libuv/test/test-shutdown-eof.c +184 -0
  178. data/deps/libuv/test/test-signal-multiple-loops.c +270 -0
  179. data/deps/libuv/test/test-signal.c +152 -0
  180. data/deps/libuv/test/test-spawn.c +938 -0
  181. data/deps/libuv/test/test-stdio-over-pipes.c +250 -0
  182. data/deps/libuv/test/test-tcp-bind-error.c +198 -0
  183. data/deps/libuv/test/test-tcp-bind6-error.c +159 -0
  184. data/deps/libuv/test/test-tcp-close-while-connecting.c +81 -0
  185. data/deps/libuv/test/test-tcp-close.c +130 -0
  186. data/deps/libuv/test/test-tcp-connect-error-after-write.c +96 -0
  187. data/deps/libuv/test/test-tcp-connect-error.c +71 -0
  188. data/deps/libuv/test/test-tcp-connect-timeout.c +86 -0
  189. data/deps/libuv/test/test-tcp-connect6-error.c +69 -0
  190. data/deps/libuv/test/test-tcp-flags.c +52 -0
  191. data/deps/libuv/test/test-tcp-open.c +175 -0
  192. data/deps/libuv/test/test-tcp-read-stop.c +73 -0
  193. data/deps/libuv/test/test-tcp-shutdown-after-write.c +132 -0
  194. data/deps/libuv/test/test-tcp-unexpected-read.c +114 -0
  195. data/deps/libuv/test/test-tcp-write-to-half-open-connection.c +136 -0
  196. data/deps/libuv/test/test-tcp-writealot.c +171 -0
  197. data/deps/libuv/test/test-thread.c +183 -0
  198. data/deps/libuv/test/test-threadpool-cancel.c +311 -0
  199. data/deps/libuv/test/test-threadpool.c +77 -0
  200. data/deps/libuv/test/test-timer-again.c +142 -0
  201. data/deps/libuv/test/test-timer.c +266 -0
  202. data/deps/libuv/test/test-tty.c +111 -0
  203. data/deps/libuv/test/test-udp-dgram-too-big.c +87 -0
  204. data/deps/libuv/test/test-udp-ipv6.c +158 -0
  205. data/deps/libuv/test/test-udp-multicast-join.c +140 -0
  206. data/deps/libuv/test/test-udp-multicast-ttl.c +87 -0
  207. data/deps/libuv/test/test-udp-open.c +154 -0
  208. data/deps/libuv/test/test-udp-options.c +87 -0
  209. data/deps/libuv/test/test-udp-send-and-recv.c +210 -0
  210. data/deps/libuv/test/test-util.c +97 -0
  211. data/deps/libuv/test/test-walk-handles.c +78 -0
  212. data/deps/libuv/uv.gyp +431 -0
  213. data/deps/libuv/vcbuild.bat +128 -0
  214. data/ext/rbuv/debug.h +27 -0
  215. data/ext/rbuv/error.c +7 -0
  216. data/ext/rbuv/error.h +10 -0
  217. data/ext/rbuv/extconf.rb +35 -0
  218. data/ext/rbuv/handle.c +40 -0
  219. data/ext/rbuv/handle.h +14 -0
  220. data/ext/rbuv/libuv.mk +12 -0
  221. data/ext/rbuv/loop.c +50 -0
  222. data/ext/rbuv/loop.h +13 -0
  223. data/ext/rbuv/rbuv.c +15 -0
  224. data/ext/rbuv/rbuv.h +27 -0
  225. data/ext/rbuv/timer.c +133 -0
  226. data/ext/rbuv/timer.h +13 -0
  227. data/lib/rbuv/timer.rb +7 -0
  228. data/lib/rbuv/version.rb +1 -1
  229. data/lib/rbuv.rb +24 -2
  230. data/rbuv.gemspec +5 -1
  231. data/spec/spec_helper.rb +22 -0
  232. data/spec/timer_spec.rb +144 -0
  233. metadata +278 -9
@@ -0,0 +1,259 @@
1
+ /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to
5
+ * deal in the Software without restriction, including without limitation the
6
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
+ * sell copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in
11
+ * all copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19
+ * IN THE SOFTWARE.
20
+ */
21
+
22
+ #ifndef UV_UNIX_INTERNAL_H_
23
+ #define UV_UNIX_INTERNAL_H_
24
+
25
+ #include "uv-common.h"
26
+
27
+ #include <assert.h>
28
+ #include <stdlib.h> /* abort */
29
+
30
+ #if defined(__STRICT_ANSI__)
31
+ # define inline __inline
32
+ #endif
33
+
34
+ #if defined(__linux__)
35
+ # include "linux-syscalls.h"
36
+ #endif /* __linux__ */
37
+
38
+ #if defined(__sun)
39
+ # include <sys/port.h>
40
+ # include <port.h>
41
+ # define futimes(fd, tv) futimesat(fd, (void*)0, tv)
42
+ #endif /* __sun */
43
+
44
+ #if defined(__APPLE__) && !TARGET_OS_IPHONE
45
+ # include <CoreServices/CoreServices.h>
46
+ #endif
47
+
48
+ #define STATIC_ASSERT(expr) \
49
+ void uv__static_assert(int static_assert_failed[0 - !(expr)])
50
+
51
+ #define ACCESS_ONCE(type, var) \
52
+ (*(volatile type*) &(var))
53
+
54
+ #define UNREACHABLE() \
55
+ do { \
56
+ assert(0 && "unreachable code"); \
57
+ abort(); \
58
+ } \
59
+ while (0)
60
+
61
+ #define SAVE_ERRNO(block) \
62
+ do { \
63
+ int _saved_errno = errno; \
64
+ do { block; } while (0); \
65
+ errno = _saved_errno; \
66
+ } \
67
+ while (0)
68
+
69
+ #if defined(__linux__)
70
+ # define UV__POLLIN UV__EPOLLIN
71
+ # define UV__POLLOUT UV__EPOLLOUT
72
+ # define UV__POLLERR UV__EPOLLERR
73
+ # define UV__POLLHUP UV__EPOLLHUP
74
+ #endif
75
+
76
+ #if defined(__sun)
77
+ # define UV__POLLIN POLLIN
78
+ # define UV__POLLOUT POLLOUT
79
+ # define UV__POLLERR POLLERR
80
+ # define UV__POLLHUP POLLHUP
81
+ #endif
82
+
83
+ #ifndef UV__POLLIN
84
+ # define UV__POLLIN 1
85
+ #endif
86
+
87
+ #ifndef UV__POLLOUT
88
+ # define UV__POLLOUT 2
89
+ #endif
90
+
91
+ #ifndef UV__POLLERR
92
+ # define UV__POLLERR 4
93
+ #endif
94
+
95
+ #ifndef UV__POLLHUP
96
+ # define UV__POLLHUP 8
97
+ #endif
98
+
99
+ /* handle flags */
100
+ enum {
101
+ UV_CLOSING = 0x01, /* uv_close() called but not finished. */
102
+ UV_CLOSED = 0x02, /* close(2) finished. */
103
+ UV_STREAM_READING = 0x04, /* uv_read_start() called. */
104
+ UV_STREAM_SHUTTING = 0x08, /* uv_shutdown() called but not complete. */
105
+ UV_STREAM_SHUT = 0x10, /* Write side closed. */
106
+ UV_STREAM_READABLE = 0x20, /* The stream is readable */
107
+ UV_STREAM_WRITABLE = 0x40, /* The stream is writable */
108
+ UV_STREAM_BLOCKING = 0x80, /* Synchronous writes. */
109
+ UV_TCP_NODELAY = 0x100, /* Disable Nagle. */
110
+ UV_TCP_KEEPALIVE = 0x200, /* Turn on keep-alive. */
111
+ UV_TCP_SINGLE_ACCEPT = 0x400 /* Only accept() when idle. */
112
+ };
113
+
114
+ /* core */
115
+ int uv__nonblock(int fd, int set);
116
+ int uv__cloexec(int fd, int set);
117
+ int uv__socket(int domain, int type, int protocol);
118
+ int uv__dup(int fd);
119
+ void uv__make_close_pending(uv_handle_t* handle);
120
+
121
+ void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd);
122
+ void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events);
123
+ void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events);
124
+ void uv__io_close(uv_loop_t* loop, uv__io_t* w);
125
+ void uv__io_feed(uv_loop_t* loop, uv__io_t* w);
126
+ int uv__io_active(const uv__io_t* w, unsigned int events);
127
+ void uv__io_poll(uv_loop_t* loop, int timeout); /* in milliseconds or -1 */
128
+
129
+ /* async */
130
+ void uv__async_send(struct uv__async* wa);
131
+ void uv__async_init(struct uv__async* wa);
132
+ int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb);
133
+ void uv__async_stop(uv_loop_t* loop, struct uv__async* wa);
134
+
135
+ /* loop */
136
+ int uv__loop_init(uv_loop_t* loop, int default_loop);
137
+ void uv__loop_delete(uv_loop_t* loop);
138
+ void uv__run_idle(uv_loop_t* loop);
139
+ void uv__run_check(uv_loop_t* loop);
140
+ void uv__run_prepare(uv_loop_t* loop);
141
+
142
+ /* error */
143
+ uv_err_code uv_translate_sys_error(int sys_errno);
144
+ void uv_fatal_error(const int errorno, const char* syscall);
145
+
146
+ /* stream */
147
+ void uv__stream_init(uv_loop_t* loop, uv_stream_t* stream,
148
+ uv_handle_type type);
149
+ int uv__stream_open(uv_stream_t*, int fd, int flags);
150
+ void uv__stream_destroy(uv_stream_t* stream);
151
+ #if defined(__APPLE__)
152
+ int uv__stream_try_select(uv_stream_t* stream, int* fd);
153
+ #endif /* defined(__APPLE__) */
154
+ void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events);
155
+ int uv__accept(int sockfd);
156
+
157
+ /* tcp */
158
+ int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb);
159
+ int uv__tcp_nodelay(int fd, int on);
160
+ int uv__tcp_keepalive(int fd, int on, unsigned int delay);
161
+
162
+ /* pipe */
163
+ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb);
164
+
165
+ /* timer */
166
+ void uv__run_timers(uv_loop_t* loop);
167
+ int uv__next_timeout(const uv_loop_t* loop);
168
+
169
+ /* signal */
170
+ void uv__signal_close(uv_signal_t* handle);
171
+ void uv__signal_global_once_init(void);
172
+ void uv__signal_loop_cleanup(uv_loop_t* loop);
173
+
174
+ /* thread pool */
175
+ void uv__work_submit(uv_loop_t* loop,
176
+ struct uv__work *w,
177
+ void (*work)(struct uv__work *w),
178
+ void (*done)(struct uv__work *w, int status));
179
+ void uv__work_done(uv_async_t* handle, int status);
180
+
181
+ /* platform specific */
182
+ uint64_t uv__hrtime(void);
183
+ int uv__kqueue_init(uv_loop_t* loop);
184
+ int uv__platform_loop_init(uv_loop_t* loop, int default_loop);
185
+ void uv__platform_loop_delete(uv_loop_t* loop);
186
+
187
+ /* various */
188
+ void uv__async_close(uv_async_t* handle);
189
+ void uv__check_close(uv_check_t* handle);
190
+ void uv__fs_event_close(uv_fs_event_t* handle);
191
+ void uv__idle_close(uv_idle_t* handle);
192
+ void uv__pipe_close(uv_pipe_t* handle);
193
+ void uv__poll_close(uv_poll_t* handle);
194
+ void uv__prepare_close(uv_prepare_t* handle);
195
+ void uv__process_close(uv_process_t* handle);
196
+ void uv__stream_close(uv_stream_t* handle);
197
+ void uv__tcp_close(uv_tcp_t* handle);
198
+ void uv__timer_close(uv_timer_t* handle);
199
+ void uv__udp_close(uv_udp_t* handle);
200
+ void uv__udp_finish_close(uv_udp_t* handle);
201
+
202
+ #if defined(__APPLE__)
203
+ int uv___stream_fd(uv_stream_t* handle);
204
+ #define uv__stream_fd(handle) (uv___stream_fd((uv_stream_t*) (handle)))
205
+ #else
206
+ #define uv__stream_fd(handle) ((handle)->io_watcher.fd)
207
+ #endif /* defined(__APPLE__) */
208
+
209
+ #ifdef UV__O_NONBLOCK
210
+ # define UV__F_NONBLOCK UV__O_NONBLOCK
211
+ #else
212
+ # define UV__F_NONBLOCK 1
213
+ #endif
214
+
215
+ int uv__make_socketpair(int fds[2], int flags);
216
+ int uv__make_pipe(int fds[2], int flags);
217
+
218
+ #if defined(__APPLE__)
219
+ typedef void (*cf_loop_signal_cb)(void*);
220
+
221
+ void uv__cf_loop_signal(uv_loop_t* loop, cf_loop_signal_cb cb, void* arg);
222
+
223
+ int uv__fsevents_init(uv_fs_event_t* handle);
224
+ int uv__fsevents_close(uv_fs_event_t* handle);
225
+
226
+ /* OSX < 10.7 has no file events, polyfill them */
227
+ #ifndef MAC_OS_X_VERSION_10_7
228
+
229
+ static const int kFSEventStreamCreateFlagFileEvents = 0x00000010;
230
+ static const int kFSEventStreamEventFlagItemCreated = 0x00000100;
231
+ static const int kFSEventStreamEventFlagItemRemoved = 0x00000200;
232
+ static const int kFSEventStreamEventFlagItemInodeMetaMod = 0x00000400;
233
+ static const int kFSEventStreamEventFlagItemRenamed = 0x00000800;
234
+ static const int kFSEventStreamEventFlagItemModified = 0x00001000;
235
+ static const int kFSEventStreamEventFlagItemFinderInfoMod = 0x00002000;
236
+ static const int kFSEventStreamEventFlagItemChangeOwner = 0x00004000;
237
+ static const int kFSEventStreamEventFlagItemXattrMod = 0x00008000;
238
+ static const int kFSEventStreamEventFlagItemIsFile = 0x00010000;
239
+ static const int kFSEventStreamEventFlagItemIsDir = 0x00020000;
240
+ static const int kFSEventStreamEventFlagItemIsSymlink = 0x00040000;
241
+
242
+ #endif /* __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070 */
243
+
244
+ #endif /* defined(__APPLE__) */
245
+
246
+ __attribute__((unused))
247
+ static void uv__req_init(uv_loop_t* loop, uv_req_t* req, uv_req_type type) {
248
+ req->type = type;
249
+ uv__req_register(loop, req);
250
+ }
251
+ #define uv__req_init(loop, req, type) \
252
+ uv__req_init((loop), (uv_req_t*)(req), (type))
253
+
254
+ __attribute__((unused))
255
+ static void uv__update_time(uv_loop_t* loop) {
256
+ loop->time = uv__hrtime() / 1000000;
257
+ }
258
+
259
+ #endif /* UV_UNIX_INTERNAL_H_ */
@@ -0,0 +1,347 @@
1
+ /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
3
+ * of this software and associated documentation files (the "Software"), to
4
+ * deal in the Software without restriction, including without limitation the
5
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
6
+ * sell copies of the Software, and to permit persons to whom the Software is
7
+ * furnished to do so, subject to the following conditions:
8
+ *
9
+ * The above copyright notice and this permission notice shall be included in
10
+ * all copies or substantial portions of the Software.
11
+ *
12
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
18
+ * IN THE SOFTWARE.
19
+ */
20
+
21
+ #include "uv.h"
22
+ #include "internal.h"
23
+
24
+ #include <assert.h>
25
+ #include <stdlib.h>
26
+ #include <string.h>
27
+ #include <errno.h>
28
+
29
+ #include <sys/sysctl.h>
30
+ #include <sys/types.h>
31
+ #include <sys/event.h>
32
+ #include <sys/time.h>
33
+ #include <unistd.h>
34
+ #include <fcntl.h>
35
+ #include <time.h>
36
+
37
+ static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags);
38
+
39
+
40
+ int uv__kqueue_init(uv_loop_t* loop) {
41
+ loop->backend_fd = kqueue();
42
+
43
+ if (loop->backend_fd == -1)
44
+ return -1;
45
+
46
+ uv__cloexec(loop->backend_fd, 1);
47
+
48
+ return 0;
49
+ }
50
+
51
+
52
+ void uv__io_poll(uv_loop_t* loop, int timeout) {
53
+ struct kevent events[1024];
54
+ struct kevent* ev;
55
+ struct timespec spec;
56
+ unsigned int nevents;
57
+ unsigned int revents;
58
+ ngx_queue_t* q;
59
+ uint64_t base;
60
+ uint64_t diff;
61
+ uv__io_t* w;
62
+ int filter;
63
+ int fflags;
64
+ int count;
65
+ int nfds;
66
+ int fd;
67
+ int op;
68
+ int i;
69
+
70
+ if (loop->nfds == 0) {
71
+ assert(ngx_queue_empty(&loop->watcher_queue));
72
+ return;
73
+ }
74
+
75
+ nevents = 0;
76
+
77
+ while (!ngx_queue_empty(&loop->watcher_queue)) {
78
+ q = ngx_queue_head(&loop->watcher_queue);
79
+ ngx_queue_remove(q);
80
+ ngx_queue_init(q);
81
+
82
+ w = ngx_queue_data(q, uv__io_t, watcher_queue);
83
+ assert(w->pevents != 0);
84
+ assert(w->fd >= 0);
85
+ assert(w->fd < (int) loop->nwatchers);
86
+
87
+ if ((w->events & UV__POLLIN) == 0 && (w->pevents & UV__POLLIN) != 0) {
88
+ filter = EVFILT_READ;
89
+ fflags = 0;
90
+ op = EV_ADD;
91
+
92
+ if (w->cb == uv__fs_event) {
93
+ filter = EVFILT_VNODE;
94
+ fflags = NOTE_ATTRIB | NOTE_WRITE | NOTE_RENAME
95
+ | NOTE_DELETE | NOTE_EXTEND | NOTE_REVOKE;
96
+ op = EV_ADD | EV_ONESHOT; /* Stop the event from firing repeatedly. */
97
+ }
98
+
99
+ EV_SET(events + nevents, w->fd, filter, op, fflags, 0, 0);
100
+
101
+ if (++nevents == ARRAY_SIZE(events)) {
102
+ if (kevent(loop->backend_fd, events, nevents, NULL, 0, NULL))
103
+ abort();
104
+ nevents = 0;
105
+ }
106
+ }
107
+
108
+ if ((w->events & UV__POLLOUT) == 0 && (w->pevents & UV__POLLOUT) != 0) {
109
+ EV_SET(events + nevents, w->fd, EVFILT_WRITE, EV_ADD, 0, 0, 0);
110
+
111
+ if (++nevents == ARRAY_SIZE(events)) {
112
+ if (kevent(loop->backend_fd, events, nevents, NULL, 0, NULL))
113
+ abort();
114
+ nevents = 0;
115
+ }
116
+ }
117
+
118
+ w->events = w->pevents;
119
+ }
120
+
121
+ assert(timeout >= -1);
122
+ base = loop->time;
123
+ count = 48; /* Benchmarks suggest this gives the best throughput. */
124
+
125
+ for (;; nevents = 0) {
126
+ if (timeout != -1) {
127
+ spec.tv_sec = timeout / 1000;
128
+ spec.tv_nsec = (timeout % 1000) * 1000000;
129
+ }
130
+
131
+ nfds = kevent(loop->backend_fd,
132
+ events,
133
+ nevents,
134
+ events,
135
+ ARRAY_SIZE(events),
136
+ timeout == -1 ? NULL : &spec);
137
+
138
+ /* Update loop->time unconditionally. It's tempting to skip the update when
139
+ * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
140
+ * operating system didn't reschedule our process while in the syscall.
141
+ */
142
+ SAVE_ERRNO(uv__update_time(loop));
143
+
144
+ if (nfds == 0) {
145
+ assert(timeout != -1);
146
+ return;
147
+ }
148
+
149
+ if (nfds == -1) {
150
+ if (errno != EINTR)
151
+ abort();
152
+
153
+ if (timeout == 0)
154
+ return;
155
+
156
+ if (timeout == -1)
157
+ continue;
158
+
159
+ /* Interrupted by a signal. Update timeout and poll again. */
160
+ goto update_timeout;
161
+ }
162
+
163
+ nevents = 0;
164
+
165
+ for (i = 0; i < nfds; i++) {
166
+ ev = events + i;
167
+ fd = ev->ident;
168
+ w = loop->watchers[fd];
169
+
170
+ if (w == NULL) {
171
+ /* File descriptor that we've stopped watching, disarm it. */
172
+ /* TODO batch up */
173
+ struct kevent events[1];
174
+
175
+ EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0);
176
+ if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL))
177
+ if (errno != EBADF && errno != ENOENT)
178
+ abort();
179
+
180
+ continue;
181
+ }
182
+
183
+ if (ev->filter == EVFILT_VNODE) {
184
+ assert(w->events == UV__POLLIN);
185
+ assert(w->pevents == UV__POLLIN);
186
+ w->cb(loop, w, ev->fflags); /* XXX always uv__fs_event() */
187
+ nevents++;
188
+ continue;
189
+ }
190
+
191
+ revents = 0;
192
+
193
+ if (ev->filter == EVFILT_READ) {
194
+ if (w->events & UV__POLLIN) {
195
+ revents |= UV__POLLIN;
196
+ w->rcount = ev->data;
197
+ } else {
198
+ /* TODO batch up */
199
+ struct kevent events[1];
200
+ EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0);
201
+ if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL))
202
+ if (errno != ENOENT)
203
+ abort();
204
+ }
205
+ }
206
+
207
+ if (ev->filter == EVFILT_WRITE) {
208
+ if (w->events & UV__POLLOUT) {
209
+ revents |= UV__POLLOUT;
210
+ w->wcount = ev->data;
211
+ } else {
212
+ /* TODO batch up */
213
+ struct kevent events[1];
214
+ EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0);
215
+ if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL))
216
+ if (errno != ENOENT)
217
+ abort();
218
+ }
219
+ }
220
+
221
+ if (ev->flags & EV_ERROR)
222
+ revents |= UV__POLLERR;
223
+
224
+ if (revents == 0)
225
+ continue;
226
+
227
+ w->cb(loop, w, revents);
228
+ nevents++;
229
+ }
230
+
231
+ if (nevents != 0) {
232
+ if (nfds == ARRAY_SIZE(events) && --count != 0) {
233
+ /* Poll for more events but don't block this time. */
234
+ timeout = 0;
235
+ continue;
236
+ }
237
+ return;
238
+ }
239
+
240
+ if (timeout == 0)
241
+ return;
242
+
243
+ if (timeout == -1)
244
+ continue;
245
+
246
+ update_timeout:
247
+ assert(timeout > 0);
248
+
249
+ diff = loop->time - base;
250
+ if (diff >= (uint64_t) timeout)
251
+ return;
252
+
253
+ timeout -= diff;
254
+ }
255
+ }
256
+
257
+
258
+ static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags) {
259
+ uv_fs_event_t* handle;
260
+ struct kevent ev;
261
+ int events;
262
+
263
+ handle = container_of(w, uv_fs_event_t, event_watcher);
264
+
265
+ if (fflags & (NOTE_ATTRIB | NOTE_EXTEND))
266
+ events = UV_CHANGE;
267
+ else
268
+ events = UV_RENAME;
269
+
270
+ handle->cb(handle, NULL, events, 0);
271
+
272
+ if (handle->event_watcher.fd == -1)
273
+ return;
274
+
275
+ /* Watcher operates in one-shot mode, re-arm it. */
276
+ fflags = NOTE_ATTRIB | NOTE_WRITE | NOTE_RENAME
277
+ | NOTE_DELETE | NOTE_EXTEND | NOTE_REVOKE;
278
+
279
+ EV_SET(&ev, w->fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, fflags, 0, 0);
280
+
281
+ if (kevent(loop->backend_fd, &ev, 1, NULL, 0, NULL))
282
+ abort();
283
+ }
284
+
285
+
286
+ int uv_fs_event_init(uv_loop_t* loop,
287
+ uv_fs_event_t* handle,
288
+ const char* filename,
289
+ uv_fs_event_cb cb,
290
+ int flags) {
291
+ #if defined(__APPLE__)
292
+ struct stat statbuf;
293
+ #endif /* defined(__APPLE__) */
294
+ int fd;
295
+
296
+ /* TODO open asynchronously - but how do we report back errors? */
297
+ if ((fd = open(filename, O_RDONLY)) == -1) {
298
+ uv__set_sys_error(loop, errno);
299
+ return -1;
300
+ }
301
+
302
+ uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
303
+ uv__handle_start(handle); /* FIXME shouldn't start automatically */
304
+ uv__io_init(&handle->event_watcher, uv__fs_event, fd);
305
+ handle->filename = strdup(filename);
306
+ handle->cb = cb;
307
+
308
+ #if defined(__APPLE__)
309
+ /* Nullify field to perform checks later */
310
+ handle->cf_eventstream = NULL;
311
+ handle->realpath = NULL;
312
+ handle->realpath_len = 0;
313
+ handle->cf_flags = flags;
314
+
315
+ if (fstat(fd, &statbuf))
316
+ goto fallback;
317
+ /* FSEvents works only with directories */
318
+ if (!(statbuf.st_mode & S_IFDIR))
319
+ goto fallback;
320
+
321
+ return uv__fsevents_init(handle);
322
+
323
+ fallback:
324
+ #endif /* defined(__APPLE__) */
325
+
326
+ uv__io_start(loop, &handle->event_watcher, UV__POLLIN);
327
+
328
+ return 0;
329
+ }
330
+
331
+
332
+ void uv__fs_event_close(uv_fs_event_t* handle) {
333
+ #if defined(__APPLE__)
334
+ if (uv__fsevents_close(handle))
335
+ uv__io_stop(handle->loop, &handle->event_watcher, UV__POLLIN);
336
+ #else
337
+ uv__io_stop(handle->loop, &handle->event_watcher, UV__POLLIN);
338
+ #endif /* defined(__APPLE__) */
339
+
340
+ uv__handle_stop(handle);
341
+
342
+ free(handle->filename);
343
+ handle->filename = NULL;
344
+
345
+ close(handle->event_watcher.fd);
346
+ handle->event_watcher.fd = -1;
347
+ }