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,393 @@
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 <stdio.h>
25
+ #include <stdint.h>
26
+ #include <stdlib.h>
27
+ #include <string.h>
28
+ #include <assert.h>
29
+ #include <errno.h>
30
+
31
+ #include <sys/types.h>
32
+ #include <sys/socket.h>
33
+ #include <sys/ioctl.h>
34
+ #include <net/if.h>
35
+ #include <netinet/in.h>
36
+ #include <arpa/inet.h>
37
+
38
+ #include <sys/time.h>
39
+ #include <unistd.h>
40
+ #include <fcntl.h>
41
+ #include <utmp.h>
42
+
43
+ #include <sys/protosw.h>
44
+ #include <libperfstat.h>
45
+ #include <sys/proc.h>
46
+ #include <sys/procfs.h>
47
+
48
+ uint64_t uv__hrtime(void) {
49
+ uint64_t G = 1000000000;
50
+ timebasestruct_t t;
51
+ read_wall_time(&t, TIMEBASE_SZ);
52
+ time_base_to_time(&t, TIMEBASE_SZ);
53
+ return (uint64_t) t.tb_high * G + t.tb_low;
54
+ }
55
+
56
+
57
+ /*
58
+ * We could use a static buffer for the path manipulations that we need outside
59
+ * of the function, but this function could be called by multiple consumers and
60
+ * we don't want to potentially create a race condition in the use of snprintf.
61
+ */
62
+ int uv_exepath(char* buffer, size_t* size) {
63
+ ssize_t res;
64
+ char pp[64], cwdl[PATH_MAX];
65
+ size_t cwdl_len;
66
+ struct psinfo ps;
67
+ int fd;
68
+
69
+ if (buffer == NULL)
70
+ return (-1);
71
+
72
+ if (size == NULL)
73
+ return (-1);
74
+
75
+ (void) snprintf(pp, sizeof(pp), "/proc/%lu/cwd", (unsigned long) getpid());
76
+
77
+ res = readlink(pp, cwdl, sizeof(cwdl) - 1);
78
+ if (res < 0)
79
+ return res;
80
+
81
+ cwdl[res] = '\0';
82
+ cwdl_len = res;
83
+
84
+ (void) snprintf(pp, sizeof(pp), "/proc/%lu/psinfo", (unsigned long) getpid());
85
+ fd = open(pp, O_RDONLY);
86
+ if (fd < 0)
87
+ return fd;
88
+
89
+ res = read(fd, &ps, sizeof(ps));
90
+ close(fd);
91
+ if (res < 0)
92
+ return res;
93
+
94
+ (void) snprintf(buffer, *size, "%s%s", cwdl, ps.pr_fname);
95
+ *size = strlen(buffer);
96
+ return 0;
97
+ }
98
+
99
+
100
+ uint64_t uv_get_free_memory(void) {
101
+ perfstat_memory_total_t mem_total;
102
+ int result = perfstat_memory_total(NULL, &mem_total, sizeof(mem_total), 1);
103
+ if (result == -1) {
104
+ return 0;
105
+ }
106
+ return mem_total.real_free * 4096;
107
+ }
108
+
109
+
110
+ uint64_t uv_get_total_memory(void) {
111
+ perfstat_memory_total_t mem_total;
112
+ int result = perfstat_memory_total(NULL, &mem_total, sizeof(mem_total), 1);
113
+ if (result == -1) {
114
+ return 0;
115
+ }
116
+ return mem_total.real_total * 4096;
117
+ }
118
+
119
+
120
+ void uv_loadavg(double avg[3]) {
121
+ perfstat_cpu_total_t ps_total;
122
+ int result = perfstat_cpu_total(NULL, &ps_total, sizeof(ps_total), 1);
123
+ if (result == -1) {
124
+ avg[0] = 0.; avg[1] = 0.; avg[2] = 0.;
125
+ return;
126
+ }
127
+ avg[0] = ps_total.loadavg[0] / (double)(1 << SBITS);
128
+ avg[1] = ps_total.loadavg[1] / (double)(1 << SBITS);
129
+ avg[2] = ps_total.loadavg[2] / (double)(1 << SBITS);
130
+ }
131
+
132
+
133
+ int uv_fs_event_init(uv_loop_t* loop,
134
+ uv_fs_event_t* handle,
135
+ const char* filename,
136
+ uv_fs_event_cb cb,
137
+ int flags) {
138
+ loop->counters.fs_event_init++;
139
+ uv__set_sys_error(loop, ENOSYS);
140
+ return -1;
141
+ }
142
+
143
+
144
+ void uv__fs_event_close(uv_fs_event_t* handle) {
145
+ UNREACHABLE();
146
+ }
147
+
148
+
149
+ char** uv_setup_args(int argc, char** argv) {
150
+ return argv;
151
+ }
152
+
153
+
154
+ uv_err_t uv_set_process_title(const char* title) {
155
+ return uv_ok_;
156
+ }
157
+
158
+
159
+ uv_err_t uv_get_process_title(char* buffer, size_t size) {
160
+ if (size > 0) {
161
+ buffer[0] = '\0';
162
+ }
163
+ return uv_ok_;
164
+ }
165
+
166
+
167
+ uv_err_t uv_resident_set_memory(size_t* rss) {
168
+ char pp[64];
169
+ psinfo_t psinfo;
170
+ uv_err_t err;
171
+ int fd;
172
+
173
+ (void) snprintf(pp, sizeof(pp), "/proc/%lu/psinfo", (unsigned long) getpid());
174
+
175
+ fd = open(pp, O_RDONLY);
176
+ if (fd == -1)
177
+ return uv__new_sys_error(errno);
178
+
179
+ err = uv_ok_;
180
+
181
+ if (read(fd, &psinfo, sizeof(psinfo)) == sizeof(psinfo))
182
+ *rss = (size_t)psinfo.pr_rssize * 1024;
183
+ else
184
+ err = uv__new_sys_error(EINVAL);
185
+
186
+ close(fd);
187
+
188
+ return err;
189
+ }
190
+
191
+
192
+ uv_err_t uv_uptime(double* uptime) {
193
+ struct utmp *utmp_buf;
194
+ size_t entries = 0;
195
+ time_t boot_time;
196
+
197
+ utmpname(UTMP_FILE);
198
+
199
+ setutent();
200
+
201
+ while ((utmp_buf = getutent()) != NULL) {
202
+ if (utmp_buf->ut_user[0] && utmp_buf->ut_type == USER_PROCESS)
203
+ ++entries;
204
+ if (utmp_buf->ut_type == BOOT_TIME)
205
+ boot_time = utmp_buf->ut_time;
206
+ }
207
+
208
+ endutent();
209
+
210
+ if (boot_time == 0)
211
+ return uv__new_artificial_error(UV_ENOSYS);
212
+
213
+ *uptime = time(NULL) - boot_time;
214
+ return uv_ok_;
215
+ }
216
+
217
+
218
+ uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
219
+ uv_cpu_info_t* cpu_info;
220
+ perfstat_cpu_total_t ps_total;
221
+ perfstat_cpu_t* ps_cpus;
222
+ perfstat_id_t cpu_id;
223
+ int result, ncpus, idx = 0;
224
+
225
+ result = perfstat_cpu_total(NULL, &ps_total, sizeof(ps_total), 1);
226
+ if (result == -1) {
227
+ return uv__new_artificial_error(UV_ENOSYS);
228
+ }
229
+
230
+ ncpus = result = perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0);
231
+ if (result == -1) {
232
+ return uv__new_artificial_error(UV_ENOSYS);
233
+ }
234
+
235
+ ps_cpus = (perfstat_cpu_t*) malloc(ncpus * sizeof(perfstat_cpu_t));
236
+ if (!ps_cpus) {
237
+ return uv__new_artificial_error(UV_ENOMEM);
238
+ }
239
+
240
+ strcpy(cpu_id.name, FIRST_CPU);
241
+ result = perfstat_cpu(&cpu_id, ps_cpus, sizeof(perfstat_cpu_t), ncpus);
242
+ if (result == -1) {
243
+ free(ps_cpus);
244
+ return uv__new_artificial_error(UV_ENOSYS);
245
+ }
246
+
247
+ *cpu_infos = (uv_cpu_info_t*) malloc(ncpus * sizeof(uv_cpu_info_t));
248
+ if (!*cpu_infos) {
249
+ free(ps_cpus);
250
+ return uv__new_artificial_error(UV_ENOMEM);
251
+ }
252
+
253
+ *count = ncpus;
254
+
255
+ cpu_info = *cpu_infos;
256
+ while (idx < ncpus) {
257
+ cpu_info->speed = (int)(ps_total.processorHZ / 1000000);
258
+ cpu_info->model = strdup(ps_total.description);
259
+ cpu_info->cpu_times.user = ps_cpus[idx].user;
260
+ cpu_info->cpu_times.sys = ps_cpus[idx].sys;
261
+ cpu_info->cpu_times.idle = ps_cpus[idx].idle;
262
+ cpu_info->cpu_times.irq = ps_cpus[idx].wait;
263
+ cpu_info->cpu_times.nice = 0;
264
+ cpu_info++;
265
+ idx++;
266
+ }
267
+
268
+ free(ps_cpus);
269
+ return uv_ok_;
270
+ }
271
+
272
+
273
+ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
274
+ int i;
275
+
276
+ for (i = 0; i < count; ++i) {
277
+ free(cpu_infos[i].model);
278
+ }
279
+
280
+ free(cpu_infos);
281
+ }
282
+
283
+
284
+ uv_err_t uv_interface_addresses(uv_interface_address_t** addresses,
285
+ int* count) {
286
+ uv_interface_address_t* address;
287
+ int sockfd, size = 1;
288
+ struct ifconf ifc;
289
+ struct ifreq *ifr, *p, flg;
290
+
291
+ *count = 0;
292
+
293
+ if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) {
294
+ return uv__new_artificial_error(UV_ENOSYS);
295
+ }
296
+
297
+ if (ioctl(sockfd, SIOCGSIZIFCONF, &size) == -1) {
298
+ close(sockfd);
299
+ return uv__new_artificial_error(UV_ENOSYS);
300
+ }
301
+
302
+ ifc.ifc_req = (struct ifreq*)malloc(size);
303
+ ifc.ifc_len = size;
304
+ if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
305
+ close(sockfd);
306
+ return uv__new_artificial_error(UV_ENOSYS);
307
+ }
308
+
309
+ #define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p))
310
+
311
+ /* Count all up and running ipv4/ipv6 addresses */
312
+ ifr = ifc.ifc_req;
313
+ while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
314
+ p = ifr;
315
+ ifr = (struct ifreq*)
316
+ ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
317
+
318
+ if (!(p->ifr_addr.sa_family == AF_INET6 ||
319
+ p->ifr_addr.sa_family == AF_INET))
320
+ continue;
321
+
322
+ memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
323
+ if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
324
+ close(sockfd);
325
+ return uv__new_artificial_error(UV_ENOSYS);
326
+ }
327
+
328
+ if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
329
+ continue;
330
+
331
+ (*count)++;
332
+ }
333
+
334
+ /* Alloc the return interface structs */
335
+ *addresses = (uv_interface_address_t*)
336
+ malloc(*count * sizeof(uv_interface_address_t));
337
+ if (!(*addresses)) {
338
+ close(sockfd);
339
+ return uv__new_artificial_error(UV_ENOMEM);
340
+ }
341
+ address = *addresses;
342
+
343
+ ifr = ifc.ifc_req;
344
+ while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
345
+ p = ifr;
346
+ ifr = (struct ifreq*)
347
+ ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
348
+
349
+ if (!(p->ifr_addr.sa_family == AF_INET6 ||
350
+ p->ifr_addr.sa_family == AF_INET))
351
+ continue;
352
+
353
+ memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
354
+ if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
355
+ close(sockfd);
356
+ return uv__new_artificial_error(UV_ENOSYS);
357
+ }
358
+
359
+ if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
360
+ continue;
361
+
362
+ /* All conditions above must match count loop */
363
+
364
+ address->name = strdup(p->ifr_name);
365
+
366
+ if (p->ifr_addr.sa_family == AF_INET6) {
367
+ address->address.address6 = *((struct sockaddr_in6 *)&p->ifr_addr);
368
+ } else {
369
+ address->address.address4 = *((struct sockaddr_in *)&p->ifr_addr);
370
+ }
371
+
372
+ address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0;
373
+
374
+ address++;
375
+ }
376
+
377
+ #undef ADDR_SIZE
378
+
379
+ close(sockfd);
380
+ return uv_ok_;
381
+ }
382
+
383
+
384
+ void uv_free_interface_addresses(uv_interface_address_t* addresses,
385
+ int count) {
386
+ int i;
387
+
388
+ for (i = 0; i < count; ++i) {
389
+ free(addresses[i].name);
390
+ }
391
+
392
+ free(addresses);
393
+ }
@@ -0,0 +1,281 @@
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
+ /* This file contains both the uv__async internal infrastructure and the
22
+ * user-facing uv_async_t functions.
23
+ */
24
+
25
+ #include "uv.h"
26
+ #include "internal.h"
27
+
28
+ #include <errno.h>
29
+ #include <assert.h>
30
+ #include <stdlib.h>
31
+ #include <string.h>
32
+ #include <unistd.h>
33
+
34
+ static void uv__async_event(uv_loop_t* loop,
35
+ struct uv__async* w,
36
+ unsigned int nevents);
37
+ static int uv__async_make_pending(int* pending);
38
+ static int uv__async_eventfd(void);
39
+
40
+
41
+ int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
42
+ if (uv__async_start(loop, &loop->async_watcher, uv__async_event))
43
+ return uv__set_sys_error(loop, errno);
44
+
45
+ uv__handle_init(loop, (uv_handle_t*)handle, UV_ASYNC);
46
+ handle->async_cb = async_cb;
47
+ handle->pending = 0;
48
+
49
+ ngx_queue_insert_tail(&loop->async_handles, &handle->queue);
50
+ uv__handle_start(handle);
51
+
52
+ return 0;
53
+ }
54
+
55
+
56
+ int uv_async_send(uv_async_t* handle) {
57
+ if (uv__async_make_pending(&handle->pending) == 0)
58
+ uv__async_send(&handle->loop->async_watcher);
59
+
60
+ return 0;
61
+ }
62
+
63
+
64
+ void uv__async_close(uv_async_t* handle) {
65
+ ngx_queue_remove(&handle->queue);
66
+ uv__handle_stop(handle);
67
+ }
68
+
69
+
70
+ static void uv__async_event(uv_loop_t* loop,
71
+ struct uv__async* w,
72
+ unsigned int nevents) {
73
+ ngx_queue_t* q;
74
+ uv_async_t* h;
75
+
76
+ ngx_queue_foreach(q, &loop->async_handles) {
77
+ h = ngx_queue_data(q, uv_async_t, queue);
78
+ if (!h->pending) continue;
79
+ h->pending = 0;
80
+ h->async_cb(h, 0);
81
+ }
82
+ }
83
+
84
+
85
+ static int uv__async_make_pending(int* pending) {
86
+ /* Do a cheap read first. */
87
+ if (ACCESS_ONCE(int, *pending) != 0)
88
+ return 1;
89
+
90
+ /* Micro-optimization: use atomic memory operations to detect if we've been
91
+ * preempted by another thread and don't have to make an expensive syscall.
92
+ * This speeds up the heavily contended case by about 1-2% and has little
93
+ * if any impact on the non-contended case.
94
+ *
95
+ * Use XCHG instead of the CMPXCHG that __sync_val_compare_and_swap() emits
96
+ * on x86, it's about 4x faster. It probably makes zero difference in the
97
+ * grand scheme of things but I'm OCD enough not to let this one pass.
98
+ */
99
+ #if defined(__i386__) || defined(__x86_64__)
100
+ {
101
+ unsigned int val = 1;
102
+ __asm__ __volatile__ ("xchgl %0, %1"
103
+ : "+r" (val)
104
+ : "m" (*pending));
105
+ return val != 0;
106
+ }
107
+ #elif defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 0)
108
+ return __sync_val_compare_and_swap(pending, 0, 1) != 0;
109
+ #else
110
+ ACCESS_ONCE(int, *pending) = 1;
111
+ return 0;
112
+ #endif
113
+ }
114
+
115
+
116
+ static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
117
+ struct uv__async* wa;
118
+ char buf[1024];
119
+ unsigned n;
120
+ ssize_t r;
121
+
122
+ n = 0;
123
+ for (;;) {
124
+ r = read(w->fd, buf, sizeof(buf));
125
+
126
+ if (r > 0)
127
+ n += r;
128
+
129
+ if (r == sizeof(buf))
130
+ continue;
131
+
132
+ if (r != -1)
133
+ break;
134
+
135
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
136
+ break;
137
+
138
+ if (errno == EINTR)
139
+ continue;
140
+
141
+ abort();
142
+ }
143
+
144
+ wa = container_of(w, struct uv__async, io_watcher);
145
+
146
+ #if defined(__linux__)
147
+ if (wa->wfd == -1) {
148
+ uint64_t val;
149
+ assert(n == sizeof(val));
150
+ memcpy(&val, buf, sizeof(val)); /* Avoid alignment issues. */
151
+ wa->cb(loop, wa, val);
152
+ return;
153
+ }
154
+ #endif
155
+
156
+ wa->cb(loop, wa, n);
157
+ }
158
+
159
+
160
+ void uv__async_send(struct uv__async* wa) {
161
+ const void* buf;
162
+ ssize_t len;
163
+ int fd;
164
+ int r;
165
+
166
+ buf = "";
167
+ len = 1;
168
+ fd = wa->wfd;
169
+
170
+ #if defined(__linux__)
171
+ if (fd == -1) {
172
+ static const uint64_t val = 1;
173
+ buf = &val;
174
+ len = sizeof(val);
175
+ fd = wa->io_watcher.fd; /* eventfd */
176
+ }
177
+ #endif
178
+
179
+ do
180
+ r = write(fd, buf, len);
181
+ while (r == -1 && errno == EINTR);
182
+
183
+ if (r == len)
184
+ return;
185
+
186
+ if (r == -1)
187
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
188
+ return;
189
+
190
+ abort();
191
+ }
192
+
193
+
194
+ void uv__async_init(struct uv__async* wa) {
195
+ wa->io_watcher.fd = -1;
196
+ wa->wfd = -1;
197
+ }
198
+
199
+
200
+ int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb) {
201
+ int pipefd[2];
202
+ int fd;
203
+
204
+ if (wa->io_watcher.fd != -1)
205
+ return 0;
206
+
207
+ fd = uv__async_eventfd();
208
+ if (fd >= 0) {
209
+ pipefd[0] = fd;
210
+ pipefd[1] = -1;
211
+ }
212
+ else if (fd != -ENOSYS)
213
+ return -1;
214
+ else if (uv__make_pipe(pipefd, UV__F_NONBLOCK))
215
+ return -1;
216
+
217
+ uv__io_init(&wa->io_watcher, uv__async_io, pipefd[0]);
218
+ uv__io_start(loop, &wa->io_watcher, UV__POLLIN);
219
+ wa->wfd = pipefd[1];
220
+ wa->cb = cb;
221
+
222
+ return 0;
223
+ }
224
+
225
+
226
+ void uv__async_stop(uv_loop_t* loop, struct uv__async* wa) {
227
+ if (wa->io_watcher.fd == -1)
228
+ return;
229
+
230
+ uv__io_stop(loop, &wa->io_watcher, UV__POLLIN);
231
+ close(wa->io_watcher.fd);
232
+ wa->io_watcher.fd = -1;
233
+
234
+ if (wa->wfd != -1) {
235
+ close(wa->wfd);
236
+ wa->wfd = -1;
237
+ }
238
+ }
239
+
240
+
241
+ static int uv__async_eventfd() {
242
+ #if defined(__linux__)
243
+ static int no_eventfd2;
244
+ static int no_eventfd;
245
+ int fd;
246
+
247
+ if (no_eventfd2)
248
+ goto skip_eventfd2;
249
+
250
+ fd = uv__eventfd2(0, UV__EFD_CLOEXEC | UV__EFD_NONBLOCK);
251
+ if (fd != -1)
252
+ return fd;
253
+
254
+ if (errno != ENOSYS)
255
+ return -errno;
256
+
257
+ no_eventfd2 = 1;
258
+
259
+ skip_eventfd2:
260
+
261
+ if (no_eventfd)
262
+ goto skip_eventfd;
263
+
264
+ fd = uv__eventfd(0);
265
+ if (fd != -1) {
266
+ uv__cloexec(fd, 1);
267
+ uv__nonblock(fd, 1);
268
+ return fd;
269
+ }
270
+
271
+ if (errno != ENOSYS)
272
+ return -errno;
273
+
274
+ no_eventfd = 1;
275
+
276
+ skip_eventfd:
277
+
278
+ #endif
279
+
280
+ return -ENOSYS;
281
+ }