]> git.lizzy.rs Git - rust.git/blob - src/rt/rust_uv.cpp
ac5ea4bb3b36b29d6426043777f5e23a636eec88
[rust.git] / src / rt / rust_uv.cpp
1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 #ifdef __WIN32__
12 // For alloca
13 #include <malloc.h>
14 #endif
15
16 #ifndef __WIN32__
17 // for signal
18 #include <signal.h>
19 #endif
20
21 #include "uv.h"
22
23 #include "rust_globals.h"
24
25 extern "C" void*
26 rust_uv_loop_new() {
27 // XXX libuv doesn't always ignore SIGPIPE even though we don't need it.
28 #ifndef __WIN32__
29     signal(SIGPIPE, SIG_IGN);
30 #endif
31     return (void*)uv_loop_new();
32 }
33
34 extern "C" void
35 rust_uv_loop_delete(uv_loop_t* loop) {
36     // FIXME: This is a workaround for #1815. libev uses realloc(0) to
37     // free the loop, which valgrind doesn't like. We have suppressions
38     // to make valgrind ignore them.
39     //
40     // Valgrind also has a sanity check when collecting allocation backtraces
41     // that the stack pointer must be at least 512 bytes into the stack (at
42     // least 512 bytes of frames must have come before). When this is not
43     // the case it doesn't collect the backtrace.
44     //
45     // Unfortunately, with our spaghetti stacks that valgrind check triggers
46     // sometimes and we don't get the backtrace for the realloc(0), it
47     // fails to be suppressed, and it gets reported as 0 bytes lost
48     // from a malloc with no backtrace.
49     //
50     // This pads our stack with some extra space before deleting the loop
51     alloca(512);
52     uv_loop_delete(loop);
53 }
54
55 extern "C" void
56 rust_uv_loop_set_data(uv_loop_t* loop, void* data) {
57     loop->data = data;
58 }
59
60 extern "C" void
61 rust_uv_run(uv_loop_t* loop) {
62     uv_run(loop, UV_RUN_DEFAULT);
63 }
64
65 extern "C" void
66 rust_uv_close(uv_handle_t* handle, uv_close_cb cb) {
67     uv_close(handle, cb);
68 }
69
70 extern "C" void
71 rust_uv_walk(uv_loop_t* loop, uv_walk_cb cb, void* arg) {
72     uv_walk(loop, cb, arg);
73 }
74
75 extern "C" void
76 rust_uv_async_send(uv_async_t* handle) {
77     uv_async_send(handle);
78 }
79
80 extern "C" int
81 rust_uv_async_init(uv_loop_t* loop_handle,
82         uv_async_t* async_handle,
83         uv_async_cb cb) {
84     return uv_async_init(loop_handle, async_handle, cb);
85 }
86
87 extern "C" int
88 rust_uv_timer_init(uv_loop_t* loop, uv_timer_t* timer) {
89     return uv_timer_init(loop, timer);
90 }
91
92 extern "C" int
93 rust_uv_timer_start(uv_timer_t* the_timer, uv_timer_cb cb,
94                     int64_t timeout, int64_t repeat) {
95     return uv_timer_start(the_timer, cb, timeout, repeat);
96 }
97
98 extern "C" int
99 rust_uv_timer_stop(uv_timer_t* the_timer) {
100     return uv_timer_stop(the_timer);
101 }
102
103 extern "C" int
104 rust_uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) {
105     return uv_tcp_init(loop, handle);
106 }
107
108 extern "C" int
109 rust_uv_tcp_connect(uv_connect_t* connect_ptr,
110         uv_tcp_t* tcp_ptr,
111         uv_connect_cb cb,
112         sockaddr_in* addr_ptr) {
113     // FIXME ref #2064
114     sockaddr_in addr = *addr_ptr;
115     int result = uv_tcp_connect(connect_ptr, tcp_ptr, addr, cb);
116     return result;
117 }
118
119 extern "C" int
120 rust_uv_tcp_bind(uv_tcp_t* tcp_server, sockaddr_in* addr_ptr) {
121     // FIXME ref #2064
122     sockaddr_in addr = *addr_ptr;
123     return uv_tcp_bind(tcp_server, addr);
124 }
125 extern "C" int
126 rust_uv_tcp_connect6(uv_connect_t* connect_ptr,
127         uv_tcp_t* tcp_ptr,
128         uv_connect_cb cb,
129         sockaddr_in6* addr_ptr) {
130     // FIXME ref #2064
131     sockaddr_in6 addr = *addr_ptr;
132     int result = uv_tcp_connect6(connect_ptr, tcp_ptr, addr, cb);
133     return result;
134 }
135
136 extern "C" int
137 rust_uv_tcp_bind6
138 (uv_tcp_t* tcp_server, sockaddr_in6* addr_ptr) {
139     // FIXME ref #2064
140     sockaddr_in6 addr = *addr_ptr;
141     return uv_tcp_bind6(tcp_server, addr);
142 }
143
144 extern "C" int
145 rust_uv_tcp_getpeername
146 (uv_tcp_t* handle, sockaddr_storage* name) {
147     // sockaddr_storage is big enough to hold either
148     // sockaddr_in or sockaddr_in6
149     int namelen = sizeof(sockaddr_in);
150     return uv_tcp_getpeername(handle, (sockaddr*)name, &namelen);
151 }
152
153 extern "C" int
154 rust_uv_tcp_getsockname
155 (uv_tcp_t* handle, sockaddr_storage* name) {
156     // sockaddr_storage is big enough to hold either
157     // sockaddr_in or sockaddr_in6
158     int namelen = sizeof(sockaddr_storage);
159     return uv_tcp_getsockname(handle, (sockaddr*)name, &namelen);
160 }
161
162 extern "C" int
163 rust_uv_tcp_nodelay
164 (uv_tcp_t* handle, int enable) {
165     return uv_tcp_nodelay(handle, enable);
166 }
167
168 extern "C" int
169 rust_uv_tcp_keepalive
170 (uv_tcp_t* handle, int enable, unsigned int delay) {
171     return uv_tcp_keepalive(handle, enable, delay);
172 }
173
174 extern "C" int
175 rust_uv_tcp_simultaneous_accepts
176 (uv_tcp_t* handle, int enable) {
177     return uv_tcp_simultaneous_accepts(handle, enable);
178 }
179
180 extern "C" int
181 rust_uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
182     return uv_udp_init(loop, handle);
183 }
184
185 extern "C" int
186 rust_uv_udp_bind(uv_udp_t* server, sockaddr_in* addr_ptr, unsigned flags) {
187     return uv_udp_bind(server, *addr_ptr, flags);
188 }
189
190 extern "C" int
191 rust_uv_udp_bind6(uv_udp_t* server, sockaddr_in6* addr_ptr, unsigned flags) {
192     return uv_udp_bind6(server, *addr_ptr, flags);
193 }
194
195 extern "C" int
196 rust_uv_udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t* buf_in,
197                  int buf_cnt, sockaddr_in* addr_ptr, uv_udp_send_cb cb) {
198     return uv_udp_send(req, handle, buf_in, buf_cnt, *addr_ptr, cb);
199 }
200
201 extern "C" int
202 rust_uv_udp_send6(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t* buf_in,
203                   int buf_cnt, sockaddr_in6* addr_ptr, uv_udp_send_cb cb) {
204     return uv_udp_send6(req, handle, buf_in, buf_cnt, *addr_ptr, cb);
205 }
206
207 extern "C" int
208 rust_uv_udp_recv_start(uv_udp_t* server, uv_alloc_cb on_alloc, uv_udp_recv_cb on_read) {
209     return uv_udp_recv_start(server, on_alloc, on_read);
210 }
211
212 extern "C" int
213 rust_uv_udp_recv_stop(uv_udp_t* server) {
214     return uv_udp_recv_stop(server);
215 }
216
217 extern "C" uv_udp_t*
218 rust_uv_get_udp_handle_from_send_req(uv_udp_send_t* send_req) {
219     return send_req->handle;
220 }
221
222 extern "C" int
223 rust_uv_udp_getsockname
224 (uv_udp_t* handle, sockaddr_storage* name) {
225     // sockaddr_storage is big enough to hold either
226     // sockaddr_in or sockaddr_in6
227     int namelen = sizeof(sockaddr_storage);
228     return uv_udp_getsockname(handle, (sockaddr*)name, &namelen);
229 }
230
231 extern "C" int
232 rust_uv_udp_set_membership
233 (uv_udp_t* handle, const char* m_addr, const char* i_addr, uv_membership membership) {
234     return uv_udp_set_membership(handle, m_addr, i_addr, membership);
235 }
236
237 extern "C" int
238 rust_uv_udp_set_multicast_loop
239 (uv_udp_t* handle, int on) {
240     return uv_udp_set_multicast_loop(handle, on);
241 }
242
243 extern "C" int
244 rust_uv_udp_set_multicast_ttl
245 (uv_udp_t* handle, int ttl) {
246     return uv_udp_set_multicast_ttl(handle, ttl);
247 }
248
249 extern "C" int
250 rust_uv_udp_set_ttl
251 (uv_udp_t* handle, int ttl) {
252     return uv_udp_set_ttl(handle, ttl);
253 }
254
255 extern "C" int
256 rust_uv_udp_set_broadcast
257 (uv_udp_t* handle, int on) {
258     return uv_udp_set_broadcast(handle, on);
259 }
260
261 extern "C" int
262 rust_uv_listen(uv_stream_t* stream, int backlog,
263         uv_connection_cb cb) {
264     return uv_listen(stream, backlog, cb);
265 }
266
267 extern "C" int
268 rust_uv_accept(uv_stream_t* server, uv_stream_t* client) {
269     return uv_accept(server, client);
270 }
271
272 extern "C" uv_stream_t*
273 rust_uv_get_stream_handle_from_connect_req(uv_connect_t* connect) {
274     return connect->handle;
275 }
276 extern "C" uv_stream_t*
277 rust_uv_get_stream_handle_from_write_req(uv_write_t* write_req) {
278     return write_req->handle;
279 }
280
281 extern "C" void
282 rust_uv_buf_init(uv_buf_t* out_buf, char* base, size_t len) {
283     *out_buf = uv_buf_init(base, len);
284 }
285
286 extern "C" uv_loop_t*
287 rust_uv_get_loop_for_uv_handle(uv_handle_t* handle) {
288     return handle->loop;
289 }
290
291 extern "C" void*
292 rust_uv_get_data_for_uv_loop(uv_loop_t* loop) {
293     return loop->data;
294 }
295
296 extern "C" void
297 rust_uv_set_data_for_uv_loop(uv_loop_t* loop,
298         void* data) {
299     loop->data = data;
300 }
301
302 extern "C" void*
303 rust_uv_get_data_for_uv_handle(uv_handle_t* handle) {
304     return handle->data;
305 }
306
307 extern "C" void
308 rust_uv_set_data_for_uv_handle(uv_handle_t* handle, void* data) {
309     handle->data = data;
310 }
311
312 extern "C" void*
313 rust_uv_get_data_for_req(uv_req_t* req) {
314     return req->data;
315 }
316
317 extern "C" void
318 rust_uv_set_data_for_req(uv_req_t* req, void* data) {
319     req->data = data;
320 }
321
322 extern "C" char*
323 rust_uv_get_base_from_buf(uv_buf_t buf) {
324     return buf.base;
325 }
326
327 extern "C" size_t
328 rust_uv_get_len_from_buf(uv_buf_t buf) {
329     return buf.len;
330 }
331
332 extern "C" uv_err_t
333 rust_uv_last_error(uv_loop_t* loop) {
334     return uv_last_error(loop);
335 }
336
337 extern "C" const char*
338 rust_uv_strerror(uv_err_t* err_ptr) {
339     uv_err_t err = *err_ptr;
340     return uv_strerror(err);
341 }
342
343 extern "C" const char*
344 rust_uv_err_name(uv_err_t* err_ptr) {
345     uv_err_t err = *err_ptr;
346     return uv_err_name(err);
347 }
348
349 extern "C" int
350 rust_uv_write(uv_write_t* req, uv_stream_t* handle,
351         uv_buf_t* bufs, int buf_cnt,
352         uv_write_cb cb) {
353     return uv_write(req, handle, bufs, buf_cnt, cb);
354 }
355 extern "C" int
356 rust_uv_read_start(uv_stream_t* stream, uv_alloc_cb on_alloc,
357         uv_read_cb on_read) {
358     return uv_read_start(stream, on_alloc, on_read);
359 }
360
361 extern "C" int
362 rust_uv_read_stop(uv_stream_t* stream) {
363     return uv_read_stop(stream);
364 }
365
366 extern "C" struct sockaddr_in
367 rust_uv_ip4_addr(const char* ip, int port) {
368     struct sockaddr_in addr = uv_ip4_addr(ip, port);
369     return addr;
370 }
371 extern "C" struct sockaddr_in6
372 rust_uv_ip6_addr(const char* ip, int port) {
373     return uv_ip6_addr(ip, port);
374 }
375
376 extern "C" struct sockaddr_in*
377 rust_uv_ip4_addrp(const char* ip, int port) {
378   struct sockaddr_in addr = uv_ip4_addr(ip, port);
379   struct sockaddr_in *addrp = (sockaddr_in*)malloc(sizeof(struct sockaddr_in));
380   assert(addrp);
381   memcpy(addrp, &addr, sizeof(struct sockaddr_in));
382   return addrp;
383 }
384 extern "C" struct sockaddr_in6*
385 rust_uv_ip6_addrp(const char* ip, int port) {
386   struct sockaddr_in6 addr = uv_ip6_addr(ip, port);
387   struct sockaddr_in6 *addrp = (sockaddr_in6*)malloc(sizeof(struct sockaddr_in6));
388   assert(addrp);
389   memcpy(addrp, &addr, sizeof(struct sockaddr_in6));
390   return addrp;
391 }
392
393 extern "C" struct sockaddr_storage *
394 rust_uv_malloc_sockaddr_storage() {
395     struct sockaddr_storage *ss = (sockaddr_storage *)malloc(sizeof(struct sockaddr_storage));
396     return ss;
397 }
398
399 extern "C" void
400 rust_uv_free_sockaddr_storage(struct sockaddr_storage *ss) {
401     free(ss);
402 }
403
404 extern "C" void
405 rust_uv_free_ip4_addr(sockaddr_in *addrp) {
406   free(addrp);
407 }
408
409 extern "C" void
410 rust_uv_free_ip6_addr(sockaddr_in6 *addrp) {
411   free(addrp);
412 }
413
414 extern "C" int
415 rust_uv_ip4_name(struct sockaddr_in* src, char* dst, size_t size) {
416     return uv_ip4_name(src, dst, size);
417 }
418 extern "C" int
419 rust_uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size) {
420     int result = uv_ip6_name(src, dst, size);
421     return result;
422 }
423 extern "C" unsigned int
424 rust_uv_ip4_port(struct sockaddr_in* src) {
425     return ntohs(src->sin_port);
426 }
427 extern "C" unsigned int
428 rust_uv_ip6_port(struct sockaddr_in6* src) {
429     return ntohs(src->sin6_port);
430 }
431
432 extern  "C" int
433 rust_uv_getaddrinfo(uv_loop_t* loop, uv_getaddrinfo_t* handle,
434                     uv_getaddrinfo_cb cb,
435                     char* node, char* service,
436                     addrinfo* hints) {
437     return uv_getaddrinfo(loop, handle, cb, node, service, hints);
438 }
439 extern "C" void
440 rust_uv_freeaddrinfo(addrinfo* res) {
441     uv_freeaddrinfo(res);
442 }
443
444 extern "C" int
445 rust_uv_is_ipv4_sockaddr(sockaddr* addr) {
446     return addr->sa_family == AF_INET;
447 }
448
449 extern "C" int
450 rust_uv_is_ipv6_sockaddr(sockaddr* addr) {
451     return addr->sa_family == AF_INET6;
452 }
453
454 extern "C" bool
455 rust_uv_is_ipv4_addrinfo(addrinfo* input) {
456     return input->ai_family == AF_INET;
457 }
458
459 extern "C" bool
460 rust_uv_is_ipv6_addrinfo(addrinfo* input) {
461     return input->ai_family == AF_INET6;
462 }
463 extern "C" addrinfo*
464 rust_uv_get_next_addrinfo(addrinfo* input) {
465     return input->ai_next;
466 }
467 extern "C" sockaddr_in*
468 rust_uv_addrinfo_as_sockaddr_in(addrinfo* input) {
469     return (sockaddr_in*)input->ai_addr;
470 }
471 extern "C" sockaddr_in6*
472 rust_uv_addrinfo_as_sockaddr_in6(addrinfo* input) {
473     return (sockaddr_in6*)input->ai_addr;
474 }
475
476 extern "C" uv_idle_t*
477 rust_uv_idle_new() {
478   return new uv_idle_t;
479 }
480
481 extern "C" void
482 rust_uv_idle_delete(uv_idle_t* handle) {
483   delete handle;
484 }
485
486 extern "C" int
487 rust_uv_idle_init(uv_loop_t* loop, uv_idle_t* idle) {
488   return uv_idle_init(loop, idle);
489 }
490
491 extern "C" int
492 rust_uv_idle_start(uv_idle_t* idle, uv_idle_cb cb) {
493   return uv_idle_start(idle, cb);
494 }
495
496 extern "C" int
497 rust_uv_idle_stop(uv_idle_t* idle) {
498   return uv_idle_stop(idle);
499 }
500
501 extern "C" size_t
502 rust_uv_handle_size(uintptr_t type) {
503   return uv_handle_size((uv_handle_type)type);
504 }
505
506 extern "C" size_t
507 rust_uv_req_size(uintptr_t type) {
508   return uv_req_size((uv_req_type)type);
509 }
510
511 extern "C" uintptr_t
512 rust_uv_handle_type_max() {
513   return UV_HANDLE_TYPE_MAX;
514 }
515
516 extern "C" uintptr_t
517 rust_uv_req_type_max() {
518   return UV_REQ_TYPE_MAX;
519 }
520
521 extern "C" int
522 rust_uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
523                 int mode, uv_fs_cb cb) {
524   return uv_fs_open(loop, req, path, flags, mode, cb);
525 }
526 extern "C" int
527 rust_uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
528   return uv_fs_unlink(loop, req, path, cb);
529 }
530 extern "C" int
531 rust_uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file fd, void* buf,
532                  size_t len, int64_t offset, uv_fs_cb cb) {
533   return uv_fs_write(loop, req, fd, buf, len, offset, cb);
534 }
535 extern "C" int
536 rust_uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file fd, void* buf,
537                  size_t len, int64_t offset, uv_fs_cb cb) {
538   return uv_fs_read(loop, req, fd, buf, len, offset, cb);
539 }
540 extern "C" int
541 rust_uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
542   return uv_fs_close(loop, req, fd, cb);
543 }
544 extern "C" void
545 rust_uv_fs_req_cleanup(uv_fs_t* req) {
546   uv_fs_req_cleanup(req);
547 }
548 extern "C" int
549 rust_uv_get_result_from_fs_req(uv_fs_t* req) {
550   return req->result;
551 }
552 extern "C" uv_loop_t*
553 rust_uv_get_loop_from_fs_req(uv_fs_t* req) {
554   return req->loop;
555 }
556
557 extern "C" uv_loop_t*
558 rust_uv_get_loop_from_getaddrinfo_req(uv_getaddrinfo_t* req) {
559   return req->loop;
560 }