ext/libuv/include/uv.h in libuv-0.10.2 vs ext/libuv/include/uv.h in libuv-0.10.3

- old
+ new

@@ -44,32 +44,27 @@ #else # define UV_EXTERN /* nothing */ #endif #include "uv-errno.h" +#include <stddef.h> #if defined(_MSC_VER) && _MSC_VER < 1600 # include "stdint-msvc2008.h" #else # include <stdint.h> #endif -#include <sys/types.h> /* size_t */ - -#if defined(__SVR4) && !defined(__unix__) -# define __unix__ -#endif - -#if defined(__unix__) || defined(__POSIX__) || \ - defined(__APPLE__) || defined(_AIX) -# include "uv-unix.h" -#else +#if defined(_WIN32) # include "uv-win.h" +#else +# include "uv-unix.h" #endif /* Expand this list if necessary. */ #define UV_ERRNO_MAP(XX) \ + XX(E2BIG, "argument list too long") \ XX(EACCES, "permission denied") \ XX(EADDRINUSE, "address already in use") \ XX(EADDRNOTAVAIL, "address not available") \ XX(EAFNOSUPPORT, "address family not supported") \ XX(EAGAIN, "resource temporarily unavailable") \ @@ -308,11 +303,11 @@ * * The timestamp increases monotonically from some arbitrary point in time. * Don't make assumptions about the starting point, you will only get * disappointed. * - * Use uv_hrtime() if you need sub-milliseond granularity. + * Use uv_hrtime() if you need sub-millisecond granularity. */ UV_EXTERN uint64_t uv_now(uv_loop_t*); /* * Get backend file descriptor. Only kqueue, epoll and event ports are @@ -336,43 +331,49 @@ */ UV_EXTERN int uv_backend_timeout(const uv_loop_t*); /* - * Should return a buffer that libuv can use to read data into. + * Should prepare a buffer that libuv can use to read data into. * * `suggested_size` is a hint. Returning a buffer that is smaller is perfectly * okay as long as `buf.len > 0`. * * If you return a buffer with `buf.len == 0`, libuv skips the read and calls * your read or recv callback with nread=UV_ENOBUFS. * * Note that returning a zero-length buffer does not stop the handle, call * uv_read_stop() or uv_udp_recv_stop() for that. */ -typedef uv_buf_t (*uv_alloc_cb)(uv_handle_t* handle, size_t suggested_size); +typedef void (*uv_alloc_cb)(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf); /* * `nread` is > 0 if there is data available, 0 if libuv is done reading for * now, or < 0 on error. * * The callee is responsible for closing the stream when an error happens. * Trying to read from the stream again is undefined. * * The callee is responsible for freeing the buffer, libuv does not reuse it. - * The buffer may be a null buffer (where buf.base=NULL and buf.len=0) on EOF - * or error. + * The buffer may be a null buffer (where buf->base=NULL and buf->len=0) on + * EOF or error. */ -typedef void (*uv_read_cb)(uv_stream_t* stream, ssize_t nread, uv_buf_t buf); +typedef void (*uv_read_cb)(uv_stream_t* stream, + ssize_t nread, + const uv_buf_t* buf); /* * Just like the uv_read_cb except that if the pending parameter is true * then you can use uv_accept() to pull the new handle into the process. * If no handle is pending then pending will be UV_UNKNOWN_HANDLE. */ -typedef void (*uv_read2_cb)(uv_pipe_t* pipe, ssize_t nread, uv_buf_t buf, - uv_handle_type pending); +typedef void (*uv_read2_cb)(uv_pipe_t* pipe, + ssize_t nread, + const uv_buf_t* buf, + uv_handle_type pending); typedef void (*uv_write_cb)(uv_write_t* req, int status); typedef void (*uv_connect_cb)(uv_connect_t* req, int status); typedef void (*uv_shutdown_cb)(uv_shutdown_t* req, int status); typedef void (*uv_connection_cb)(uv_stream_t* server, int status); @@ -382,11 +383,11 @@ /* TODO: do these really need a status argument? */ typedef void (*uv_async_cb)(uv_async_t* handle, int status); typedef void (*uv_prepare_cb)(uv_prepare_t* handle, int status); typedef void (*uv_check_cb)(uv_check_t* handle, int status); typedef void (*uv_idle_cb)(uv_idle_t* handle, int status); -typedef void (*uv_exit_cb)(uv_process_t*, int exit_status, int term_signal); +typedef void (*uv_exit_cb)(uv_process_t*, int64_t exit_status, int term_signal); typedef void (*uv_walk_cb)(uv_handle_t* handle, void* arg); typedef void (*uv_fs_cb)(uv_fs_t* req); typedef void (*uv_work_cb)(uv_work_t* req); typedef void (*uv_after_work_cb)(uv_work_t* req, int status); typedef void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* req, @@ -514,12 +515,28 @@ * Returns size of request types, useful for dynamic lookup with FFI */ UV_EXTERN size_t uv_req_size(uv_req_type type); /* - * Returns 1 if the prepare/check/idle/timer handle has been started, 0 - * otherwise. For other handle types this always returns 1. + * Returns non-zero if the handle is active, zero if it's inactive. + * + * What "active" means depends on the type of handle: + * + * - A uv_async_t handle is always active and cannot be deactivated, except + * by closing it with uv_close(). + * + * - A uv_pipe_t, uv_tcp_t, uv_udp_t, etc. handle - basically any handle that + * deals with I/O - is active when it is doing something that involves I/O, + * like reading, writing, connecting, accepting new connections, etc. + * + * - A uv_check_t, uv_idle_t, uv_timer_t, etc. handle is active when it has + * been started with a call to uv_check_start(), uv_idle_start(), etc. + * + * Rule of thumb: if a handle of type uv_foo_t has a uv_foo_start() + * function, then it's active from the moment that function is called. + * Likewise, uv_foo_stop() deactivates the handle again. + * */ UV_EXTERN int uv_is_active(const uv_handle_t* handle); /* * Walk the list of open handles. @@ -548,25 +565,10 @@ * freeing base after the uv_buf_t is done. Return struct passed by value. */ UV_EXTERN uv_buf_t uv_buf_init(char* base, unsigned int len); -/* - * Utility function. Copies up to `size` characters from `src` to `dst` - * and ensures that `dst` is properly NUL terminated unless `size` is zero. - */ -UV_EXTERN size_t uv_strlcpy(char* dst, const char* src, size_t size); - -/* - * Utility function. Appends `src` to `dst` and ensures that `dst` is - * properly NUL terminated unless `size` is zero or `dst` does not - * contain a NUL byte. `size` is the total length of `dst` so at most - * `size - strlen(dst) - 1` characters will be copied from `src`. - */ -UV_EXTERN size_t uv_strlcat(char* dst, const char* src, size_t size); - - #define UV_STREAM_FIELDS \ /* number of bytes queued for writing */ \ size_t write_queue_size; \ uv_alloc_cb alloc_cb; \ uv_read_cb read_cb; \ @@ -646,22 +648,29 @@ * // writes "1234" * uv_write(&req1, stream, a, 2); * uv_write(&req2, stream, b, 2); * */ -UV_EXTERN int uv_write(uv_write_t* req, uv_stream_t* handle, - uv_buf_t bufs[], int bufcnt, uv_write_cb cb); +UV_EXTERN int uv_write(uv_write_t* req, + uv_stream_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_write_cb cb); /* * Extended write function for sending handles over a pipe. The pipe must be * initialized with ipc == 1. * send_handle must be a TCP socket or pipe, which is a server or a connection * (listening or connected state). Bound sockets or pipes will be assumed to * be servers. */ -UV_EXTERN int uv_write2(uv_write_t* req, uv_stream_t* handle, uv_buf_t bufs[], - int bufcnt, uv_stream_t* send_handle, uv_write_cb cb); +UV_EXTERN int uv_write2(uv_write_t* req, + uv_stream_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_stream_t* send_handle, + uv_write_cb cb); /* uv_write_t is a subclass of uv_req_t */ struct uv_write_s { UV_REQ_FIELDS uv_write_cb cb; @@ -751,27 +760,39 @@ * accepting connections (which is why it is enabled by default) but * may lead to uneven load distribution in multi-process setups. */ UV_EXTERN int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable); -UV_EXTERN int uv_tcp_bind(uv_tcp_t* handle, struct sockaddr_in); -UV_EXTERN int uv_tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6); +/* + * Bind the handle to an address and port. `addr` should point to an + * initialized struct sockaddr_in or struct sockaddr_in6. + * + * When the port is already taken, you can expect to see an UV_EADDRINUSE + * error from either uv_tcp_bind(), uv_listen() or uv_tcp_connect(). + * + * That is, a successful call to uv_tcp_bind() does not guarantee that + * the call to uv_listen() or uv_tcp_connect() will succeed as well. + */ +UV_EXTERN int uv_tcp_bind(uv_tcp_t* handle, const struct sockaddr* addr); + UV_EXTERN int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name, int* namelen); UV_EXTERN int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name, int* namelen); /* - * uv_tcp_connect, uv_tcp_connect6 - * These functions establish IPv4 and IPv6 TCP connections. Provide an - * initialized TCP handle and an uninitialized uv_connect_t*. The callback - * will be made when the connection is established. + * Establish an IPv4 or IPv6 TCP connection. Provide an initialized TCP handle + * and an uninitialized uv_connect_t*. `addr` should point to an initialized + * struct sockaddr_in or struct sockaddr_in6. + * + * The callback is made when the connection has been established or when a + * connection error happened. */ -UV_EXTERN int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle, - struct sockaddr_in address, uv_connect_cb cb); -UV_EXTERN int uv_tcp_connect6(uv_connect_t* req, uv_tcp_t* handle, - struct sockaddr_in6 address, uv_connect_cb cb); +UV_EXTERN int uv_tcp_connect(uv_connect_t* req, + uv_tcp_t* handle, + const struct sockaddr* addr, + uv_connect_cb cb); /* uv_connect_t is a subclass of uv_req_t */ struct uv_connect_s { UV_REQ_FIELDS uv_connect_cb cb; @@ -783,11 +804,11 @@ /* * UDP support. */ enum uv_udp_flags { - /* Disables dual stack mode. Used with uv_udp_bind6(). */ + /* Disables dual stack mode. */ UV_UDP_IPV6ONLY = 1, /* * Indicates message was truncated because read buffer was too small. The * remainder was discarded by the OS. Used in uv_udp_recv_cb. */ @@ -812,12 +833,15 @@ * addr struct sockaddr_in or struct sockaddr_in6. * Valid for the duration of the callback only. * flags One or more OR'ed UV_UDP_* constants. * Right now only UV_UDP_PARTIAL is used. */ -typedef void (*uv_udp_recv_cb)(uv_udp_t* handle, ssize_t nread, uv_buf_t buf, - struct sockaddr* addr, unsigned flags); +typedef void (*uv_udp_recv_cb)(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* buf, + const struct sockaddr* addr, + unsigned flags); /* uv_udp_t is a subclass of uv_handle_t */ struct uv_udp_s { UV_HANDLE_FIELDS UV_UDP_PRIVATE_FIELDS @@ -843,40 +867,44 @@ * Unix only: * The only requirement of the sock argument is that it follows the * datagram contract (works in unconnected mode, supports sendmsg()/recvmsg(), * etc.). In other words, other datagram-type sockets like raw sockets or * netlink sockets can also be passed to this function. + * + * This sets the SO_REUSEPORT socket flag on the BSDs and OS X. On other + * UNIX platforms, it sets the SO_REUSEADDR flag. What that means is that + * multiple threads or processes can bind to the same address without error + * (provided they all set the flag) but only the last one to bind will receive + * any traffic, in effect "stealing" the port from the previous listener. + * This behavior is something of an anomaly and may be replaced by an explicit + * opt-in mechanism in future versions of libuv. */ UV_EXTERN int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock); /* * Bind to a IPv4 address and port. * * Arguments: * handle UDP handle. Should have been initialized with `uv_udp_init`. - * addr struct sockaddr_in with the address and port to bind to. + * addr struct sockaddr_in or struct sockaddr_in6 with the address and + * port to bind to. * flags Unused. * * Returns: * 0 on success, or an error code < 0 on failure. - */ -UV_EXTERN int uv_udp_bind(uv_udp_t* handle, struct sockaddr_in addr, - unsigned flags); - -/* - * Bind to a IPv6 address and port. * - * Arguments: - * handle UDP handle. Should have been initialized with `uv_udp_init`. - * addr struct sockaddr_in with the address and port to bind to. - * flags Should be 0 or UV_UDP_IPV6ONLY. - * - * Returns: - * 0 on success, or an error code < 0 on failure. + * This sets the SO_REUSEPORT socket flag on the BSDs and OS X. On other + * UNIX platforms, it sets the SO_REUSEADDR flag. What that means is that + * multiple threads or processes can bind to the same address without error + * (provided they all set the flag) but only the last one to bind will receive + * any traffic, in effect "stealing" the port from the previous listener. + * This behavior is something of an anomaly and may be replaced by an explicit + * opt-in mechanism in future versions of libuv. */ -UV_EXTERN int uv_udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr, - unsigned flags); +UV_EXTERN int uv_udp_bind(uv_udp_t* handle, + const struct sockaddr* addr, + unsigned int flags); UV_EXTERN int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, int* namelen); /* @@ -956,41 +984,25 @@ * * Arguments: * req UDP request handle. Need not be initialized. * handle UDP handle. Should have been initialized with `uv_udp_init`. * bufs List of buffers to send. - * bufcnt Number of buffers in `bufs`. + * nbufs Number of buffers in `bufs`. * addr Address of the remote peer. See `uv_ip4_addr`. * send_cb Callback to invoke when the data has been sent out. * * Returns: * 0 on success, or an error code < 0 on failure. */ -UV_EXTERN int uv_udp_send(uv_udp_send_t* req, uv_udp_t* handle, - uv_buf_t bufs[], int bufcnt, struct sockaddr_in addr, - uv_udp_send_cb send_cb); +UV_EXTERN int uv_udp_send(uv_udp_send_t* req, + uv_udp_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + const struct sockaddr* addr, + uv_udp_send_cb send_cb); /* - * Send data. If the socket has not previously been bound with `uv_udp_bind6`, - * it is bound to ::0 (the "all interfaces" address) and a random port number. - * - * Arguments: - * req UDP request handle. Need not be initialized. - * handle UDP handle. Should have been initialized with `uv_udp_init`. - * bufs List of buffers to send. - * bufcnt Number of buffers in `bufs`. - * addr Address of the remote peer. See `uv_ip6_addr`. - * send_cb Callback to invoke when the data has been sent out. - * - * Returns: - * 0 on success, or an error code < 0 on failure. - */ -UV_EXTERN int uv_udp_send6(uv_udp_send_t* req, uv_udp_t* handle, - uv_buf_t bufs[], int bufcnt, struct sockaddr_in6 addr, - uv_udp_send_cb send_cb); - -/* * Receive data. If the socket has not previously been bound with `uv_udp_bind` * or `uv_udp_bind6`, it is bound to 0.0.0.0 (the "all interfaces" address) * and a random port number. * * Arguments: @@ -1046,12 +1058,15 @@ UV_EXTERN int uv_tty_set_mode(uv_tty_t*, int mode); /* * To be called when the program exits. Resets TTY settings to default * values for the next process to take over. + * + * This function is async signal-safe on UNIX platforms but can fail with error + * code UV_EBUSY if you call it when execution is inside uv_tty_set_mode(). */ -UV_EXTERN void uv_tty_reset_mode(void); +UV_EXTERN int uv_tty_reset_mode(void); /* * Gets the current Window size. On success zero is returned. */ UV_EXTERN int uv_tty_get_winsize(uv_tty_t*, int* width, int* height); @@ -1086,12 +1101,24 @@ /* * Opens an existing file descriptor or HANDLE as a pipe. */ UV_EXTERN int uv_pipe_open(uv_pipe_t*, uv_file file); +/* + * Bind the pipe to a file path (UNIX) or a name (Windows.) + * + * Paths on UNIX get truncated to `sizeof(sockaddr_un.sun_path)` bytes, + * typically between 92 and 108 bytes. + */ UV_EXTERN int uv_pipe_bind(uv_pipe_t* handle, const char* name); +/* + * Connect to the UNIX domain socket or the named pipe. + * + * Paths on UNIX get truncated to `sizeof(sockaddr_un.sun_path)` bytes, + * typically between 92 and 108 bytes. + */ UV_EXTERN void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, const char* name, uv_connect_cb cb); /* * This setting applies to Windows only. @@ -1386,11 +1413,11 @@ char** env; /* * If non-null this represents a directory the subprocess should execute * in. Stands for current working directory. */ - char* cwd; + const char* cwd; /* * Various flags that control how uv_spawn() behaves. See the definition of * `enum uv_process_flags` below. */ unsigned int flags; @@ -1461,12 +1488,13 @@ int pid; UV_PROCESS_PRIVATE_FIELDS }; /* Initializes uv_process_t and starts the process. */ -UV_EXTERN int uv_spawn(uv_loop_t*, uv_process_t*, - uv_process_options_t options); +UV_EXTERN int uv_spawn(uv_loop_t* loop, + uv_process_t* handle, + const uv_process_options_t* options); /* * Kills the process with the specified signal. The user must still * call uv_close on the process. @@ -1818,21 +1846,21 @@ */ UV_EXTERN void uv_loadavg(double avg[3]); /* - * Flags to be passed to uv_fs_event_init. + * Flags to be passed to uv_fs_event_start. */ enum uv_fs_event_flags { /* * By default, if the fs event watcher is given a directory name, we will * watch for all events in that directory. This flags overrides this behavior * and makes fs_event report only changes to the directory entry itself. This * flag does not affect individual files watched. * This flag is currently not implemented yet on any backend. */ - UV_FS_EVENT_WATCH_ENTRY = 1, + UV_FS_EVENT_WATCH_ENTRY = 1, /* * By default uv_fs_event will try to use a kernel interface such as inotify * or kqueue to detect events. This may not work on remote filesystems such * as NFS mounts. This flag makes fs_event fall back to calling stat() on a @@ -1844,22 +1872,29 @@ /* * By default, event watcher, when watching directory, is not registering * (is ignoring) changes in it's subdirectories. * This flag will override this behaviour on platforms that support it. */ - UV_FS_EVENT_RECURSIVE = 3 + UV_FS_EVENT_RECURSIVE = 4 }; -UV_EXTERN int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle, - const char* filename, uv_fs_event_cb cb, int flags); +UV_EXTERN int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle); +UV_EXTERN int uv_fs_event_start(uv_fs_event_t* handle, + uv_fs_event_cb cb, + const char* filename, + unsigned int flags); + +UV_EXTERN int uv_fs_event_stop(uv_fs_event_t* handle); + + /* Utility */ /* Convert string ip addresses to binary structures */ -UV_EXTERN struct sockaddr_in uv_ip4_addr(const char* ip, int port); -UV_EXTERN struct sockaddr_in6 uv_ip6_addr(const char* ip, int port); +UV_EXTERN int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr); +UV_EXTERN int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr); /* Convert binary addresses to strings */ UV_EXTERN int uv_ip4_name(struct sockaddr_in* src, char* dst, size_t size); UV_EXTERN int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size); @@ -1993,9 +2028,21 @@ /* Runs a function once and only once. Concurrent calls to uv_once() with the * same guard will block all callers except one (it's unspecified which one). * The guard should be initialized statically with the UV_ONCE_INIT macro. */ UV_EXTERN void uv_once(uv_once_t* guard, void (*callback)(void)); + +/* Thread-local storage. These functions largely follow the semantics of + * pthread_key_create(), pthread_key_delete(), pthread_getspecific() and + * pthread_setspecific(). + * + * Note that the total thread-local storage size may be limited. + * That is, it may not be possible to create many TLS keys. + */ +UV_EXTERN int uv_key_create(uv_key_t* key); +UV_EXTERN void uv_key_delete(uv_key_t* key); +UV_EXTERN void* uv_key_get(uv_key_t* key); +UV_EXTERN void uv_key_set(uv_key_t* key, void* value); UV_EXTERN int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg); UV_EXTERN unsigned long uv_thread_self(void); UV_EXTERN int uv_thread_join(uv_thread_t *tid);