int luv_udp_recv_start(lua_State* L) { uv_udp_t* handle = (uv_udp_t*)luv_checkudata(L, 1, "udp"); int rc = uv_udp_recv_start(handle, luv_on_alloc, luv_on_udp_recv); if (rc && uv_last_error(luv_get_loop(L)).code != UV_EALREADY) { uv_err_t err = uv_last_error(luv_get_loop(L)); return luaL_error(L, "udp_recv_start: %s", uv_strerror(err)); } luv_handle_ref(L, handle->data, 1); return 0; }
int luv_close (lua_State* L) { uv_handle_t* handle = luv_checkudata(L, 1, "handle"); /* printf("close \tlhandle=%p handle=%p\n", handle->data, handle);*/ if (uv_is_closing(handle)) { fprintf(stderr, "WARNING: Handle already closing \tlhandle=%p handle=%p\n", handle->data, handle); return 0; } uv_close(handle, luv_on_close); luv_handle_ref(L, handle->data, 1); return 0; }
static int luv_udp__send(lua_State* L, int family) { uv_buf_t buf; uv_udp_t* handle = (uv_udp_t*)luv_checkudata(L, 1, "udp"); size_t len; const char* chunk = luaL_checklstring(L, 2, &len); luv_udp_ref_t *ref; uv_udp_send_t* req = (uv_udp_send_t*)malloc(sizeof(uv_udp_send_t)); int port = luaL_checkint(L, 3); const char* host = luaL_checkstring(L, 4); struct sockaddr_in dest; struct sockaddr_in6 dest6; int rc; /* Store a reference to the callback */ lua_pushvalue(L, 5); ref = malloc(sizeof(*ref)); ref->ref = luaL_ref(L, LUA_REGISTRYINDEX); req->data = ref; luv_handle_ref(L, handle->data, 1); /* Store the chunk * TODO: this is probably unsafe, should investigate */ buf = uv_buf_init((char*)chunk, len); switch(family) { case AF_INET: dest = uv_ip4_addr(host, port); rc = uv_udp_send(req, handle, &buf, 1, dest, luv_on_udp_send); break; case AF_INET6: dest6 = uv_ip6_addr(host, port); rc = uv_udp_send6(req, handle, &buf, 1, dest6, luv_on_udp_send); break; default: assert(0 && "unexpected family type"); abort(); } if (rc) { uv_err_t err = uv_last_error(luv_get_loop(L)); return luaL_error(L, "udp_send: %s", uv_strerror(err)); } return 0; }
int luv_timer_start(lua_State* L) { uv_timer_t* handle = (uv_timer_t*)luv_checkudata(L, 1, "timer"); int64_t timeout = luaL_checklong(L, 2); int64_t repeat = luaL_checklong(L, 3); luaL_checktype(L, 4, LUA_TFUNCTION); luv_register_event(L, 1, "timeout", 4); int err = uv_timer_start(handle, luv_on_timer, timeout, repeat); if (err < 0) { return luaL_error(L, "timer_start: %s", uv_strerror(err)); } luv_handle_ref(L, handle->data, 1); return 0; }
int luv_tcp_connect6(lua_State* L) { uv_tcp_t* handle = (uv_tcp_t*)luv_checkudata(L, 1, "tcp"); const char* ip_address = luaL_checkstring(L, 2); int port = luaL_checkint(L, 3); struct sockaddr_in6 address = uv_ip6_addr(ip_address, port); uv_connect_t* req = (uv_connect_t*)malloc(sizeof(uv_connect_t)); if (uv_tcp_connect6(req, handle, address, luv_after_connect)) { uv_err_t err = uv_last_error(luv_get_loop(L)); return luaL_error(L, "tcp_connect6: %s", uv_strerror(err)); } luv_handle_ref(L, handle->data, 1); return 0; }