summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/luv/src/luv.c
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/luv/src/luv.c')
-rw-r--r--3rdparty/luv/src/luv.c519
1 files changed, 519 insertions, 0 deletions
diff --git a/3rdparty/luv/src/luv.c b/3rdparty/luv/src/luv.c
new file mode 100644
index 00000000000..7b552d68d53
--- /dev/null
+++ b/3rdparty/luv/src/luv.c
@@ -0,0 +1,519 @@
+/*
+ * Copyright 2014 The Luvit Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "luv.h"
+#include "util.c"
+#include "lhandle.c"
+#include "lreq.c"
+#include "loop.c"
+#include "req.c"
+#include "handle.c"
+#include "timer.c"
+#include "prepare.c"
+#include "check.c"
+#include "idle.c"
+#include "async.c"
+#include "poll.c"
+#include "signal.c"
+#include "process.c"
+#include "stream.c"
+#include "tcp.c"
+#include "pipe.c"
+#include "tty.c"
+#include "udp.c"
+#include "fs_event.c"
+#include "fs_poll.c"
+#include "fs.c"
+#include "dns.c"
+#include "thread.c"
+#include "work.c"
+#include "misc.c"
+#include "constants.c"
+
+static const luaL_Reg luv_functions[] = {
+ // loop.c
+ {"loop_close", luv_loop_close},
+ {"run", luv_run},
+ {"loop_alive", luv_loop_alive},
+ {"stop", luv_stop},
+ {"backend_fd", luv_backend_fd},
+ {"backend_timeout", luv_backend_timeout},
+ {"now", luv_now},
+ {"update_time", luv_update_time},
+ {"walk", luv_walk},
+
+ // req.c
+ {"cancel", luv_cancel},
+
+ // handle.c
+ {"is_active", luv_is_active},
+ {"is_closing", luv_is_closing},
+ {"close", luv_close},
+ {"ref", luv_ref},
+ {"unref", luv_unref},
+ {"has_ref", luv_has_ref},
+ {"send_buffer_size", luv_send_buffer_size},
+ {"recv_buffer_size", luv_recv_buffer_size},
+ {"fileno", luv_fileno},
+
+ // timer.c
+ {"new_timer", luv_new_timer},
+ {"timer_start", luv_timer_start},
+ {"timer_stop", luv_timer_stop},
+ {"timer_again", luv_timer_again},
+ {"timer_set_repeat", luv_timer_set_repeat},
+ {"timer_get_repeat", luv_timer_get_repeat},
+
+ // prepare.c
+ {"new_prepare", luv_new_prepare},
+ {"prepare_start", luv_prepare_start},
+ {"prepare_stop", luv_prepare_stop},
+
+ // check.c
+ {"new_check", luv_new_check},
+ {"check_start", luv_check_start},
+ {"check_stop", luv_check_stop},
+
+ // idle.c
+ {"new_idle", luv_new_idle},
+ {"idle_start", luv_idle_start},
+ {"idle_stop", luv_idle_stop},
+
+ // async.c
+ {"new_async", luv_new_async},
+ {"async_send", luv_async_send},
+
+ // poll.c
+ {"new_poll", luv_new_poll},
+ {"new_socket_poll", luv_new_socket_poll},
+ {"poll_start", luv_poll_start},
+ {"poll_stop", luv_poll_stop},
+
+ // signal.c
+ {"new_signal", luv_new_signal},
+ {"signal_start", luv_signal_start},
+ {"signal_stop", luv_signal_stop},
+
+ // process.c
+ {"disable_stdio_inheritance", luv_disable_stdio_inheritance},
+ {"spawn", luv_spawn},
+ {"process_kill", luv_process_kill},
+ {"kill", luv_kill},
+
+ // stream.c
+ {"shutdown", luv_shutdown},
+ {"listen", luv_listen},
+ {"accept", luv_accept},
+ {"read_start", luv_read_start},
+ {"read_stop", luv_read_stop},
+ {"write", luv_write},
+ {"write2", luv_write2},
+ {"try_write", luv_try_write},
+ {"is_readable", luv_is_readable},
+ {"is_writable", luv_is_writable},
+ {"stream_set_blocking", luv_stream_set_blocking},
+
+ // tcp.c
+ {"new_tcp", luv_new_tcp},
+ {"tcp_open", luv_tcp_open},
+ {"tcp_nodelay", luv_tcp_nodelay},
+ {"tcp_keepalive", luv_tcp_keepalive},
+ {"tcp_simultaneous_accepts", luv_tcp_simultaneous_accepts},
+ {"tcp_bind", luv_tcp_bind},
+ {"tcp_getpeername", luv_tcp_getpeername},
+ {"tcp_getsockname", luv_tcp_getsockname},
+ {"tcp_connect", luv_tcp_connect},
+ {"tcp_write_queue_size", luv_write_queue_size},
+
+ // pipe.c
+ {"new_pipe", luv_new_pipe},
+ {"pipe_open", luv_pipe_open},
+ {"pipe_bind", luv_pipe_bind},
+ {"pipe_connect", luv_pipe_connect},
+ {"pipe_getsockname", luv_pipe_getsockname},
+ {"pipe_getpeername", luv_pipe_getpeername},
+ {"pipe_pending_instances", luv_pipe_pending_instances},
+ {"pipe_pending_count", luv_pipe_pending_count},
+ {"pipe_pending_type", luv_pipe_pending_type},
+
+ // tty.c
+ {"new_tty", luv_new_tty},
+ {"tty_set_mode", luv_tty_set_mode},
+ {"tty_reset_mode", luv_tty_reset_mode},
+ {"tty_get_winsize", luv_tty_get_winsize},
+
+ // udp.c
+ {"new_udp", luv_new_udp},
+ {"udp_open", luv_udp_open},
+ {"udp_bind", luv_udp_bind},
+ {"udp_getsockname", luv_udp_getsockname},
+ {"udp_set_membership", luv_udp_set_membership},
+ {"udp_set_multicast_loop", luv_udp_set_multicast_loop},
+ {"udp_set_multicast_ttl", luv_udp_set_multicast_ttl},
+ {"udp_set_multicast_interface", luv_udp_set_multicast_interface},
+ {"udp_set_broadcast", luv_udp_set_broadcast},
+ {"udp_set_ttl", luv_udp_set_ttl},
+ {"udp_send", luv_udp_send},
+ {"udp_try_send", luv_udp_try_send},
+ {"udp_recv_start", luv_udp_recv_start},
+ {"udp_recv_stop", luv_udp_recv_stop},
+
+ // fs_event.c
+ {"new_fs_event", luv_new_fs_event},
+ {"fs_event_start", luv_fs_event_start},
+ {"fs_event_stop", luv_fs_event_stop},
+ {"fs_event_getpath", luv_fs_event_getpath},
+
+ // fs_poll.c
+ {"new_fs_poll", luv_new_fs_poll},
+ {"fs_poll_start", luv_fs_poll_start},
+ {"fs_poll_stop", luv_fs_poll_stop},
+ {"fs_poll_getpath", luv_fs_poll_getpath},
+
+ // fs.c
+ {"fs_close", luv_fs_close},
+ {"fs_open", luv_fs_open},
+ {"fs_read", luv_fs_read},
+ {"fs_unlink", luv_fs_unlink},
+ {"fs_write", luv_fs_write},
+ {"fs_mkdir", luv_fs_mkdir},
+ {"fs_mkdtemp", luv_fs_mkdtemp},
+ {"fs_rmdir", luv_fs_rmdir},
+ {"fs_scandir", luv_fs_scandir},
+ {"fs_scandir_next", luv_fs_scandir_next},
+ {"fs_stat", luv_fs_stat},
+ {"fs_fstat", luv_fs_fstat},
+ {"fs_lstat", luv_fs_lstat},
+ {"fs_rename", luv_fs_rename},
+ {"fs_fsync", luv_fs_fsync},
+ {"fs_fdatasync", luv_fs_fdatasync},
+ {"fs_ftruncate", luv_fs_ftruncate},
+ {"fs_sendfile", luv_fs_sendfile},
+ {"fs_access", luv_fs_access},
+ {"fs_chmod", luv_fs_chmod},
+ {"fs_fchmod", luv_fs_fchmod},
+ {"fs_utime", luv_fs_utime},
+ {"fs_futime", luv_fs_futime},
+ {"fs_link", luv_fs_link},
+ {"fs_symlink", luv_fs_symlink},
+ {"fs_readlink", luv_fs_readlink},
+ {"fs_realpath", luv_fs_realpath},
+ {"fs_chown", luv_fs_chown},
+ {"fs_fchown", luv_fs_fchown},
+
+ // dns.c
+ {"getaddrinfo", luv_getaddrinfo},
+ {"getnameinfo", luv_getnameinfo},
+
+ // misc.c
+ {"chdir", luv_chdir},
+ {"os_homedir", luv_os_homedir},
+ {"cpu_info", luv_cpu_info},
+ {"cwd", luv_cwd},
+ {"exepath", luv_exepath},
+ {"get_process_title", luv_get_process_title},
+ {"get_total_memory", luv_get_total_memory},
+ {"get_free_memory", luv_get_free_memory},
+ {"getpid", luv_getpid},
+#ifndef _WIN32
+ {"getuid", luv_getuid},
+ {"setuid", luv_setuid},
+ {"getgid", luv_getgid},
+ {"setgid", luv_setgid},
+#endif
+ {"getrusage", luv_getrusage},
+ {"guess_handle", luv_guess_handle},
+ {"hrtime", luv_hrtime},
+ {"interface_addresses", luv_interface_addresses},
+ {"loadavg", luv_loadavg},
+ {"resident_set_memory", luv_resident_set_memory},
+ {"set_process_title", luv_set_process_title},
+ {"uptime", luv_uptime},
+ {"version", luv_version},
+ {"version_string", luv_version_string},
+
+ // thread.c
+ {"new_thread", luv_new_thread},
+ {"thread_equal", luv_thread_equal},
+ {"thread_self", luv_thread_self},
+ {"thread_join", luv_thread_join},
+ {"sleep", luv_thread_sleep},
+
+ // work.c
+ {"new_work", luv_new_work},
+ {"queue_work", luv_queue_work},
+
+ {NULL, NULL}
+};
+
+static const luaL_Reg luv_handle_methods[] = {
+ // handle.c
+ {"is_active", luv_is_active},
+ {"is_closing", luv_is_closing},
+ {"close", luv_close},
+ {"ref", luv_ref},
+ {"unref", luv_unref},
+ {"has_ref", luv_has_ref},
+ {"send_buffer_size", luv_send_buffer_size},
+ {"recv_buffer_size", luv_recv_buffer_size},
+ {"fileno", luv_fileno},
+ {NULL, NULL}
+};
+
+static const luaL_Reg luv_async_methods[] = {
+ {"send", luv_async_send},
+ {NULL, NULL}
+};
+
+static const luaL_Reg luv_check_methods[] = {
+ {"start", luv_check_start},
+ {"stop", luv_check_stop},
+ {NULL, NULL}
+};
+
+static const luaL_Reg luv_fs_event_methods[] = {
+ {"start", luv_fs_event_start},
+ {"stop", luv_fs_event_stop},
+ {"getpath", luv_fs_event_getpath},
+ {NULL, NULL}
+};
+
+static const luaL_Reg luv_fs_poll_methods[] = {
+ {"start", luv_fs_poll_start},
+ {"stop", luv_fs_poll_stop},
+ {"getpath", luv_fs_poll_getpath},
+ {NULL, NULL}
+};
+
+static const luaL_Reg luv_idle_methods[] = {
+ {"start", luv_idle_start},
+ {"stop", luv_idle_stop},
+ {NULL, NULL}
+};
+
+static const luaL_Reg luv_stream_methods[] = {
+ {"shutdown", luv_shutdown},
+ {"listen", luv_listen},
+ {"accept", luv_accept},
+ {"read_start", luv_read_start},
+ {"read_stop", luv_read_stop},
+ {"write", luv_write},
+ {"write2", luv_write2},
+ {"try_write", luv_try_write},
+ {"is_readable", luv_is_readable},
+ {"is_writable", luv_is_writable},
+ {"set_blocking", luv_stream_set_blocking},
+ {NULL, NULL}
+};
+
+static const luaL_Reg luv_pipe_methods[] = {
+ {"open", luv_pipe_open},
+ {"bind", luv_pipe_bind},
+ {"connect", luv_pipe_connect},
+ {"getsockname", luv_pipe_getsockname},
+ {"getpeername", luv_pipe_getpeername},
+ {"pending_instances", luv_pipe_pending_instances},
+ {"pending_count", luv_pipe_pending_count},
+ {"pending_type", luv_pipe_pending_type},
+ {NULL, NULL}
+};
+
+static const luaL_Reg luv_poll_methods[] = {
+ {"start", luv_poll_start},
+ {"stop", luv_poll_stop},
+ {NULL, NULL}
+};
+
+static const luaL_Reg luv_prepare_methods[] = {
+ {"start", luv_prepare_start},
+ {"stop", luv_prepare_stop},
+ {NULL, NULL}
+};
+
+static const luaL_Reg luv_process_methods[] = {
+ {"kill", luv_process_kill},
+ {NULL, NULL}
+};
+
+static const luaL_Reg luv_tcp_methods[] = {
+ {"open", luv_tcp_open},
+ {"nodelay", luv_tcp_nodelay},
+ {"keepalive", luv_tcp_keepalive},
+ {"simultaneous_accepts", luv_tcp_simultaneous_accepts},
+ {"bind", luv_tcp_bind},
+ {"getpeername", luv_tcp_getpeername},
+ {"getsockname", luv_tcp_getsockname},
+ {"connect", luv_tcp_connect},
+ {"write_queue_size", luv_write_queue_size},
+ {NULL, NULL}
+};
+
+static const luaL_Reg luv_timer_methods[] = {
+ {"start", luv_timer_start},
+ {"stop", luv_timer_stop},
+ {"again", luv_timer_again},
+ {"set_repeat", luv_timer_set_repeat},
+ {"get_repeat", luv_timer_get_repeat},
+ {NULL, NULL}
+};
+
+static const luaL_Reg luv_tty_methods[] = {
+ {"set_mode", luv_tty_set_mode},
+ {"get_winsize", luv_tty_get_winsize},
+ {NULL, NULL}
+};
+
+static const luaL_Reg luv_udp_methods[] = {
+ {"open", luv_udp_open},
+ {"bind", luv_udp_bind},
+ {"bindgetsockname", luv_udp_getsockname},
+ {"set_membership", luv_udp_set_membership},
+ {"set_multicast_loop", luv_udp_set_multicast_loop},
+ {"set_multicast_ttl", luv_udp_set_multicast_ttl},
+ {"set_multicast_interface", luv_udp_set_multicast_interface},
+ {"set_broadcast", luv_udp_set_broadcast},
+ {"set_ttl", luv_udp_set_ttl},
+ {"send", luv_udp_send},
+ {"try_send", luv_udp_try_send},
+ {"recv_start", luv_udp_recv_start},
+ {"recv_stop", luv_udp_recv_stop},
+ {NULL, NULL}
+};
+
+static const luaL_Reg luv_signal_methods[] = {
+ {"start", luv_signal_start},
+ {"stop", luv_signal_stop},
+ {NULL, NULL}
+};
+
+static void luv_handle_init(lua_State* L) {
+
+ lua_newtable(L);
+#define XX(uc, lc) \
+ luaL_newmetatable (L, "uv_"#lc); \
+ lua_pushcfunction(L, luv_handle_tostring); \
+ lua_setfield(L, -2, "__tostring"); \
+ lua_pushcfunction(L, luv_handle_gc); \
+ lua_setfield(L, -2, "__gc"); \
+ luaL_newlib(L, luv_##lc##_methods); \
+ luaL_setfuncs(L, luv_handle_methods, 0); \
+ lua_setfield(L, -2, "__index"); \
+ lua_pushboolean(L, 1); \
+ lua_rawset(L, -3);
+
+ UV_HANDLE_TYPE_MAP(XX)
+#undef XX
+ lua_setfield(L, LUA_REGISTRYINDEX, "uv_handle");
+
+ lua_newtable(L);
+
+ luaL_getmetatable(L, "uv_pipe");
+ lua_getfield(L, -1, "__index");
+ luaL_setfuncs(L, luv_stream_methods, 0);
+ lua_pop(L, 1);
+ lua_pushboolean(L, 1);
+ lua_rawset(L, -3);
+
+ luaL_getmetatable(L, "uv_tcp");
+ lua_getfield(L, -1, "__index");
+ luaL_setfuncs(L, luv_stream_methods, 0);
+ lua_pop(L, 1);
+ lua_pushboolean(L, 1);
+ lua_rawset(L, -3);
+
+ luaL_getmetatable(L, "uv_tty");
+ lua_getfield(L, -1, "__index");
+ luaL_setfuncs(L, luv_stream_methods, 0);
+ lua_pop(L, 1);
+ lua_pushboolean(L, 1);
+ lua_rawset(L, -3);
+
+ lua_setfield(L, LUA_REGISTRYINDEX, "uv_stream");
+}
+
+LUALIB_API lua_State* luv_state(uv_loop_t* loop) {
+ return loop->data;
+}
+
+// TODO: find out if storing this somehow in an upvalue is faster
+LUALIB_API uv_loop_t* luv_loop(lua_State* L) {
+ uv_loop_t* loop;
+ lua_pushstring(L, "uv_loop");
+ lua_rawget(L, LUA_REGISTRYINDEX);
+ loop = lua_touserdata(L, -1);
+ lua_pop(L, 1);
+ return loop;
+}
+
+static void walk_cb(uv_handle_t *handle, void *arg)
+{
+ (void)arg;
+ if (!uv_is_closing(handle)) {
+ uv_close(handle, luv_close_cb);
+ }
+}
+
+static int loop_gc(lua_State *L) {
+ uv_loop_t* loop = luv_loop(L);
+ // Call uv_close on every active handle
+ uv_walk(loop, walk_cb, NULL);
+ // Run the event loop until all handles are successfully closed
+ while (uv_loop_close(loop)) {
+ uv_run(loop, UV_RUN_DEFAULT);
+ }
+ return 0;
+}
+
+LUALIB_API int luaopen_luv (lua_State *L) {
+
+ uv_loop_t* loop;
+ int ret;
+
+ // Setup the uv_loop meta table for a proper __gc
+ luaL_newmetatable(L, "uv_loop.meta");
+ lua_pushstring(L, "__gc");
+ lua_pushcfunction(L, loop_gc);
+ lua_settable(L, -3);
+
+ loop = lua_newuserdata(L, sizeof(*loop));
+ ret = uv_loop_init(loop);
+ if (ret < 0) {
+ return luaL_error(L, "%s: %s\n", uv_err_name(ret), uv_strerror(ret));
+ }
+ // setup the metatable for __gc
+ luaL_getmetatable(L, "uv_loop.meta");
+ lua_setmetatable(L, -2);
+ // Tell the state how to find the loop.
+ lua_pushstring(L, "uv_loop");
+ lua_insert(L, -2);
+ lua_rawset(L, LUA_REGISTRYINDEX);
+ lua_pop(L, 1);
+
+ // Tell the loop how to find the state.
+ loop->data = L;
+
+ luv_req_init(L);
+ luv_handle_init(L);
+ luv_thread_init(L);
+ luv_work_init(L);
+
+ luaL_newlib(L, luv_functions);
+ luv_constants(L);
+ lua_setfield(L, -2, "constants");
+
+ return 1;
+}