/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef UV_H #define UV_H #ifdef __cplusplus extern "C" { #endif #define UV_VERSION_MAJOR 0 #define UV_VERSION_MINOR 1 #include /* int64_t */ #include /* size_t */ typedef struct uv_err_s uv_err_t; typedef struct uv_handle_s uv_handle_t; typedef struct uv_req_s uv_req_t; #if defined(__unix__) || defined(__POSIX__) || defined(__APPLE__) # include "uv-unix.h" #else # include "uv-win.h" #endif /* The status parameter is 0 if the request completed successfully, * and should be -1 if the request was cancelled or failed. * For uv_close_cb, -1 means that the handle was closed due to an error. * Error details can be obtained by calling uv_last_error(). * * In the case of uv_read_cb the uv_buf_t returned should be freed by the * user. */ typedef uv_buf_t (*uv_alloc_cb)(uv_handle_t* handle, size_t suggested_size); typedef void (*uv_read_cb)(uv_handle_t *handle, int nread, uv_buf_t buf); typedef void (*uv_write_cb)(uv_req_t* req, int status); typedef void (*uv_connect_cb)(uv_req_t* req, int status); typedef void (*uv_shutdown_cb)(uv_req_t* req, int status); typedef void (*uv_accept_cb)(uv_handle_t* handle); typedef void (*uv_close_cb)(uv_handle_t* handle, int status); /* TODO: do loop_cb and async_cb really need a status argument? */ typedef void (*uv_loop_cb)(uv_handle_t* handle, int status); typedef void (*uv_async_cb)(uv_handle_t* handle, int stats); /* Expand this list if necessary. */ typedef enum { UV_UNKNOWN = -1, UV_OK = 0, UV_EOF, UV_EACCESS, UV_EAGAIN, UV_EADDRINUSE, UV_EADDRNOTAVAIL, UV_EAFNOSUPPORT, UV_EALREADY, UV_EBADF, UV_EBUSY, UV_ECONNABORTED, UV_ECONNREFUSED, UV_ECONNRESET, UV_EDESTADDRREQ, UV_EFAULT, UV_EHOSTUNREACH, UV_EINTR, UV_EINVAL, UV_EISCONN, UV_EMFILE, UV_ENETDOWN, UV_ENETUNREACH, UV_ENFILE, UV_ENOBUFS, UV_ENOMEM, UV_ENONET, UV_ENOPROTOOPT, UV_ENOTCONN, UV_ENOTSOCK, UV_ENOTSUP, UV_EPROTO, UV_EPROTONOSUPPORT, UV_EPROTOTYPE, UV_ETIMEDOUT } uv_err_code; typedef enum { UV_UNKNOWN_HANDLE = 0, UV_TCP, UV_NAMED_PIPE, UV_TTY, UV_FILE, UV_TIMER, UV_PREPARE, UV_CHECK, UV_IDLE, UV_ASYNC } uv_handle_type; typedef enum { UV_UNKNOWN_REQ = 0, UV_CONNECT, UV_ACCEPT, UV_READ, UV_WRITE, UV_SHUTDOWN, UV_WAKEUP } uv_req_type; struct uv_err_s { /* read-only */ uv_err_code code; /* private */ int sys_errno_; }; struct uv_req_s { /* read-only */ uv_req_type type; /* public */ uv_handle_t* handle; void* cb; void* data; /* private */ uv_req_private_fields }; struct uv_handle_s { /* read-only */ uv_handle_type type; /* public */ uv_close_cb close_cb; void* data; /* number of bytes queued for writing */ size_t write_queue_size; /* private */ uv_handle_private_fields }; /* Most functions return boolean: 0 for success and -1 for failure. * On error the user should then call uv_last_error() to determine * the error code. */ uv_err_t uv_last_error(); char* uv_strerror(uv_err_t err); const char* uv_err_name(uv_err_t err); void uv_init(uv_alloc_cb alloc); int uv_run(); /* Manually modify the event loop's reference count. Useful if the user wants * to have a handle or timeout that doesn't keep the loop alive. */ void uv_ref(); void uv_unref(); void uv_update_time(); int64_t uv_now(); void uv_req_init(uv_req_t* req, uv_handle_t* handle, void* cb); /* * TODO: * - uv_(pipe|pipe_tty)_handle_init * - uv_bind_pipe(char* name) * - uv_continuous_read(uv_handle_t* handle, uv_continuous_read_cb* cb) * - A way to list cancelled uv_reqs after before/on uv_close_cb */ /* TCP socket methods. * Handle and callback bust be set by calling uv_req_init. */ int uv_tcp_init(uv_handle_t* handle, uv_close_cb close_cb, void* data); int uv_bind(uv_handle_t* handle, struct sockaddr* addr); int uv_connect(uv_req_t* req, struct sockaddr* addr); int uv_shutdown(uv_req_t* req); /* TCP server methods. */ int uv_listen(uv_handle_t* handle, int backlog, uv_accept_cb cb); /* Call this after accept_cb. client does not need to be initialized. */ int uv_accept(uv_handle_t* server, uv_handle_t* client, uv_close_cb close_cb, void* data); /* Read data from an incoming stream. The callback will be made several * several times until there is no more data to read or uv_read_stop is * called. When we've reached EOF nread will be set to -1 and the error is * set to UV_EOF. When nread == -1 the buf parameter might not point to a * valid buffer; in that case buf.len and buf.base are both set to 0. * Note that nread might also be 0, which does *not* indicate an error or * eof; it happens when libuv requested a buffer through the alloc callback * but then decided that it didn't need that buffer. */ int uv_read_start(uv_handle_t* handle, uv_read_cb cb); int uv_read_stop(uv_handle_t* handle); int uv_write(uv_req_t* req, uv_buf_t bufs[], int bufcnt); /* Timer methods */ int uv_timer_init(uv_handle_t* handle, uv_close_cb close_cb, void* data); int uv_timer_start(uv_handle_t* handle, uv_loop_cb cb, int64_t timeout, int64_t repeat); int uv_timer_stop(uv_handle_t* handle); /* * Stop the timer, and if it is repeating restart it using the repeat value * as the timeout. If the timer has never been started before it returns -1 and * sets the error to UV_EINVAL. */ int uv_timer_again(uv_handle_t* handle); /* * Set the repeat value. Note that if the repeat value is set from a timer * callback it does not immediately take effect. If the timer was nonrepeating * before, it will have been stopped. If it was repeating, then the old repeat * value will have been used to schedule the next timeout. */ void uv_timer_set_repeat(uv_handle_t* handle, int64_t repeat); int64_t uv_timer_get_repeat(uv_handle_t* handle); /* libev wrapper. Every active prepare handle gets its callback called * exactly once per loop iteration, just before the system blocks to wait * for completed i/o. */ int uv_prepare_init(uv_handle_t* handle, uv_close_cb close_cb, void* data); int uv_prepare_start(uv_handle_t* handle, uv_loop_cb cb); int uv_prepare_stop(uv_handle_t* handle); /* libev wrapper. Every active check handle gets its callback called exactly * once per loop iteration, just after the system returns from blocking. */ int uv_check_init(uv_handle_t* handle, uv_close_cb close_cb, void* data); int uv_check_start(uv_handle_t* handle, uv_loop_cb cb); int uv_check_stop(uv_handle_t* handle); /* libev wrapper. Every active idle handle gets its callback called repeatedly until it is * stopped. This happens after all other types of callbacks are processed. * When there are multiple "idle" handles active, their callbacks are called * in turn. */ int uv_idle_init(uv_handle_t* handle, uv_close_cb close_cb, void* data); int uv_idle_start(uv_handle_t* handle, uv_loop_cb cb); int uv_idle_stop(uv_handle_t* handle); /* Returns 1 if the prepare/check/idle handle has been started, 0 otherwise. * For other handle types this always returns 1. */ int uv_is_active(uv_handle_t* handle); /* libev wrapper. uv_async_send wakes up the event loop and calls the async * handle's callback There is no guarantee that every uv_async_send call * leads to exactly one invocation of the callback; The only guarantee is * that the callback function is called at least once after the call to * async_send. Unlike everything else, uv_async_send can be called from * another thread. * * QUESTION(ryan) Can UV_ASYNC just use uv_loop_cb? Same signature on my * side. */ int uv_async_init(uv_handle_t* handle, uv_async_cb async_cb, uv_close_cb close_cb, void* data); int uv_async_send(uv_handle_t* handle); /* Request handle to be closed. close_cb will be called * asynchronously after this call. */ int uv_close(uv_handle_t* handle); /* Utility */ struct sockaddr_in uv_ip4_addr(char* ip, int port); #ifdef __cplusplus } #endif #endif /* UV_H */