Skip to content

Commit

Permalink
Make luv threadsafe by tying uv_loop_t and lua_State_t* to eachother …
Browse files Browse the repository at this point in the history
…and not using globals
  • Loading branch information
creationix committed Oct 3, 2014
1 parent 3e471ae commit 1521fa2
Show file tree
Hide file tree
Showing 22 changed files with 221 additions and 156 deletions.
7 changes: 4 additions & 3 deletions src/async.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,18 @@ static uv_async_t* luv_check_async(lua_State* L, int index) {
}

static void luv_async_cb(uv_async_t* handle) {
lua_State* L = luv_state(handle->loop);
luv_handle_t* data = handle->data;
luv_find_handle(R, data);
luv_call_callback(R, data, LUV_ASYNC, 1);
luv_find_handle(L, data);
luv_call_callback(L, data, LUV_ASYNC, 1);
}

static int luv_new_async(lua_State* L) {
uv_async_t* handle;
int ret;
luaL_checktype(L, 1, LUA_TFUNCTION);
handle = lua_newuserdata(L, sizeof(*handle));
ret = uv_async_init(uv_default_loop(), handle, luv_async_cb);
ret = uv_async_init(luv_loop(L), handle, luv_async_cb);
if (ret < 0) {
lua_pop(L, 1);
return luv_error(L, ret);
Expand Down
7 changes: 4 additions & 3 deletions src/check.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ static uv_check_t* luv_check_check(lua_State* L, int index) {

static int luv_new_check(lua_State* L) {
uv_check_t* handle = lua_newuserdata(L, sizeof(*handle));
int ret = uv_check_init(uv_default_loop(), handle);
int ret = uv_check_init(luv_loop(L), handle);
if (ret < 0) {
lua_pop(L, 1);
return luv_error(L, ret);
Expand All @@ -34,9 +34,10 @@ static int luv_new_check(lua_State* L) {
}

static void luv_check_cb(uv_check_t* handle) {
lua_State* L = luv_state(handle->loop);
luv_handle_t* data = handle->data;
luv_find_handle(R, data);
luv_call_callback(R, data, LUV_CHECK, 1);
luv_find_handle(L, data);
luv_call_callback(L, data, LUV_CHECK, 1);
}

static int luv_check_start(lua_State* L) {
Expand Down
65 changes: 34 additions & 31 deletions src/dns.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,60 +22,61 @@


static void luv_getaddrinfo_cb(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
lua_State* L = luv_state(req->loop);
struct addrinfo* curr = res;
char ip[INET6_ADDRSTRLEN];
const char *addr;
int port, nargs, i = 0;

if (status < 0) {
luv_status(R, status);
luv_status(L, status);
nargs = 1;
}
else {
lua_pushnil(R);
lua_newtable(R);
lua_pushnil(L);
lua_newtable(L);
nargs = 2;
for (curr = res; curr; curr = curr->ai_next) {
if (curr->ai_family == AF_INET || curr->ai_family == AF_INET6) {
lua_newtable(R);
lua_newtable(L);
if (curr->ai_family == AF_INET) {
addr = (char*) &((struct sockaddr_in*) curr->ai_addr)->sin_addr;
port = ((struct sockaddr_in*) curr->ai_addr)->sin_port;
lua_pushstring(R, "inet");
lua_setfield(R, -2, "family");
lua_pushstring(L, "inet");
lua_setfield(L, -2, "family");
} else {
addr = (char*) &((struct sockaddr_in6*) curr->ai_addr)->sin6_addr;
port = ((struct sockaddr_in6*) curr->ai_addr)->sin6_port;
lua_pushstring(R, "inet6");
lua_setfield(R, -2, "family");
lua_pushstring(L, "inet6");
lua_setfield(L, -2, "family");
}
uv_inet_ntop(curr->ai_family, addr, ip, INET6_ADDRSTRLEN);
lua_pushstring(R, ip);
lua_setfield(R, -2, "addr");
lua_pushstring(L, ip);
lua_setfield(L, -2, "addr");
if (ntohs(port)) {
lua_pushinteger(R, ntohs(port));
lua_setfield(R, -2, "port");
lua_pushinteger(L, ntohs(port));
lua_setfield(L, -2, "port");
}
if (curr->ai_socktype == SOCK_STREAM) {
lua_pushstring(R, "stream");
lua_setfield(R, -2, "socktype");
lua_pushstring(L, "stream");
lua_setfield(L, -2, "socktype");
}
else if (curr->ai_socktype == SOCK_DGRAM) {
lua_pushstring(R, "dgram");
lua_setfield(R, -2, "socktype");
lua_pushstring(L, "dgram");
lua_setfield(L, -2, "socktype");
}
lua_pushstring(R, luv_family_to_string(curr->ai_protocol));
lua_setfield(R, -2, "protocol");
lua_pushstring(L, luv_family_to_string(curr->ai_protocol));
lua_setfield(L, -2, "protocol");
if (curr->ai_canonname) {
lua_pushstring(R, curr->ai_canonname);
lua_setfield(R, -2, "canonname");
lua_pushstring(L, curr->ai_canonname);
lua_setfield(L, -2, "canonname");
}
lua_rawseti(R, -2, ++i);
lua_rawseti(L, -2, ++i);
}
}
}
luv_fulfill_req(R, req->data, nargs);
luv_cleanup_req(R, req->data);
luv_fulfill_req(L, req->data, nargs);
luv_cleanup_req(L, req->data);
req->data = NULL;
if (res) uv_freeaddrinfo(res);
}
Expand Down Expand Up @@ -187,7 +188,7 @@ static int luv_getaddrinfo(lua_State* L) {
req = lua_newuserdata(L, sizeof(*req));
req->data = luv_setup_req(L, ref);

ret = uv_getaddrinfo(uv_default_loop(), req, luv_getaddrinfo_cb, node, service, hints);
ret = uv_getaddrinfo(luv_loop(L), req, luv_getaddrinfo_cb, node, service, hints);
if (ret < 0) {
lua_pop(L, 1);
return luv_error(L, ret);
Expand All @@ -196,21 +197,23 @@ static int luv_getaddrinfo(lua_State* L) {
}

static void luv_getnameinfo_cb(uv_getnameinfo_t* req, int status, const char* hostname, const char* service) {
lua_State* L = luv_state(req->loop);

int nargs;

if (status < 0) {
luv_status(R, status);
luv_status(L, status);
nargs = 1;
}
else {
lua_pushnil(R);
lua_pushstring(R, hostname);
lua_pushstring(R, service);
lua_pushnil(L);
lua_pushstring(L, hostname);
lua_pushstring(L, service);
nargs = 3;
}

luv_fulfill_req(R, req->data, nargs);
luv_cleanup_req(R, req->data);
luv_fulfill_req(L, req->data, nargs);
luv_cleanup_req(L, req->data);
req->data = NULL;
}

Expand Down Expand Up @@ -270,7 +273,7 @@ static int luv_getnameinfo(lua_State* L) {
req = lua_newuserdata(L, sizeof(*req));
req->data = luv_setup_req(L, ref);

ret = uv_getnameinfo(uv_default_loop(), req, luv_getnameinfo_cb, (struct sockaddr*)&addr, flags);
ret = uv_getnameinfo(luv_loop(L), req, luv_getnameinfo_cb, (struct sockaddr*)&addr, flags);
if (ret < 0) {
lua_pop(L, 1);
return luv_error(L, ret);
Expand Down
30 changes: 16 additions & 14 deletions src/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,12 @@ static void luv_push_stats_table(lua_State* L, const uv_stat_t* s) {
}

static int luv_string_to_flags(lua_State* L, const char* string) {
if (strcasecmp(string, "r") == 0) return O_RDONLY;
if (strcasecmp(string, "r+") == 0) return O_RDWR;
if (strcasecmp(string, "w") == 0) return O_CREAT | O_TRUNC | O_WRONLY;
if (strcasecmp(string, "w+") == 0) return O_CREAT | O_TRUNC | O_RDWR;
if (strcasecmp(string, "a") == 0) return O_APPEND | O_CREAT | O_WRONLY;
if (strcasecmp(string, "a+") == 0) return O_APPEND | O_CREAT | O_RDWR;
if (strcmp(string, "r") == 0) return O_RDONLY;
if (strcmp(string, "r+") == 0) return O_RDWR;
if (strcmp(string, "w") == 0) return O_CREAT | O_TRUNC | O_WRONLY;
if (strcmp(string, "w+") == 0) return O_CREAT | O_TRUNC | O_RDWR;
if (strcmp(string, "a") == 0) return O_APPEND | O_CREAT | O_WRONLY;
if (strcmp(string, "a+") == 0) return O_APPEND | O_CREAT | O_RDWR;
return luaL_error(L, "Unknown file open flag '%s'", string);
}

Expand Down Expand Up @@ -179,21 +179,23 @@ static int push_fs_result(lua_State* L, uv_fs_t* req) {
}

static void luv_fs_cb(uv_fs_t* req) {
int nargs = push_fs_result(R, req);
if (nargs == 2 && lua_isnil(R, -nargs)) {
lua_State* L = luv_state(req->loop);

int nargs = push_fs_result(L, req);
if (nargs == 2 && lua_isnil(L, -nargs)) {
// If it was an error, convert to (err, value) format.
lua_remove(R, -nargs);
lua_remove(L, -nargs);
nargs--;
}
else {
// Otherwise insert a nil in front to convert to (err, value) format.
lua_pushnil(R);
lua_insert(R, -nargs - 1);
lua_pushnil(L);
lua_insert(L, -nargs - 1);
nargs++;
}
luv_fulfill_req(R, req->data, nargs);
luv_fulfill_req(L, req->data, nargs);
if (req->fs_type != UV_FS_SCANDIR) {
luv_cleanup_req(R, req->data);
luv_cleanup_req(L, req->data);
req->data = NULL;
uv_fs_req_cleanup(req);
}
Expand All @@ -203,7 +205,7 @@ static void luv_fs_cb(uv_fs_t* req) {
int ret, sync; \
luv_req_t* data = req->data; \
sync = data->callback_ref == LUA_NOREF; \
ret = uv_fs_##func(uv_default_loop(), req, __VA_ARGS__, \
ret = uv_fs_##func(luv_loop(L), req, __VA_ARGS__, \
sync ? NULL : luv_fs_cb); \
if (ret < 0) { \
luv_cleanup_req(L, req->data); \
Expand Down
25 changes: 13 additions & 12 deletions src/fs_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ static uv_fs_event_t* luv_check_fs_event(lua_State* L, int index) {

static int luv_new_fs_event(lua_State* L) {
uv_fs_event_t* handle = lua_newuserdata(L, sizeof(*handle));
int ret = uv_fs_event_init(uv_default_loop(), handle);
int ret = uv_fs_event_init(luv_loop(L), handle);
if (ret < 0) {
lua_pop(L, 1);
return luv_error(L, ret);
Expand All @@ -35,31 +35,32 @@ static int luv_new_fs_event(lua_State* L) {
}

static void luv_fs_event_cb(uv_fs_event_t* handle, const char* filename, int events, int status) {
lua_State* L = luv_state(handle->loop);
// self
luv_find_handle(R, handle->data);
luv_find_handle(L, handle->data);

// err
luv_status(R, status);
luv_status(L, status);

// filename
lua_pushstring(R, filename);
lua_pushstring(L, filename);

// events
lua_newtable(R);
lua_newtable(L);
if (events & UV_FS_EVENT_WATCH_ENTRY) {
lua_pushboolean(R, 1);
lua_setfield(R, -2, "watch_entry");
lua_pushboolean(L, 1);
lua_setfield(L, -2, "watch_entry");
}
if (events & UV_FS_EVENT_STAT) {
lua_pushboolean(R, 1);
lua_setfield(R, -2, "stat");
lua_pushboolean(L, 1);
lua_setfield(L, -2, "stat");
}
if (events & UV_FS_EVENT_RECURSIVE) {
lua_pushboolean(R, 1);
lua_setfield(R, -2, "recursive");
lua_pushboolean(L, 1);
lua_setfield(L, -2, "recursive");
}

luv_call_callback(R, handle->data, LUV_FS_EVENT, 4);
luv_call_callback(L, handle->data, LUV_FS_EVENT, 4);
}

static int luv_fs_event_start(lua_State* L) {
Expand Down
18 changes: 10 additions & 8 deletions src/fs_poll.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ static uv_fs_poll_t* luv_check_fs_poll(lua_State* L, int index) {

static int luv_new_fs_poll(lua_State* L) {
uv_fs_poll_t* handle = lua_newuserdata(L, sizeof(*handle));
int ret = uv_fs_poll_init(uv_default_loop(), handle);
int ret = uv_fs_poll_init(luv_loop(L), handle);
if (ret < 0) {
lua_pop(L, 1);
return luv_error(L, ret);
Expand All @@ -35,29 +35,31 @@ static int luv_new_fs_poll(lua_State* L) {
}

static void luv_fs_poll_cb(uv_fs_poll_t* handle, int status, const uv_stat_t* prev, const uv_stat_t* curr) {
lua_State* L = luv_state(handle->loop);

// self
luv_find_handle(R, handle->data);
luv_find_handle(L, handle->data);

// err
luv_status(R, status);
luv_status(L, status);

// prev
if (prev) {
luv_push_stats_table(R, prev);
luv_push_stats_table(L, prev);
}
else {
lua_pushnil(R);
lua_pushnil(L);
}

// curr
if (curr) {
luv_push_stats_table(R, curr);
luv_push_stats_table(L, curr);
}
else {
lua_pushnil(R);
lua_pushnil(L);
}

luv_call_callback(R, handle->data, LUV_FS_POLL, 4);
luv_call_callback(L, handle->data, LUV_FS_POLL, 4);
}

static int luv_fs_poll_start(lua_State* L) {
Expand Down
7 changes: 4 additions & 3 deletions src/handle.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,12 @@ static int luv_is_closing(lua_State* L) {
}

static void luv_close_cb(uv_handle_t* handle) {
lua_State* L = luv_state(handle->loop);
luv_handle_t* data = handle->data;
if (!data) return;
luv_find_handle(R, data);
luv_call_callback(R, data, LUV_CLOSED, 1);
luv_cleanup_handle(R, data);
luv_find_handle(L, data);
luv_call_callback(L, data, LUV_CLOSED, 1);
luv_cleanup_handle(L, data);
handle->data = NULL;
}

Expand Down
7 changes: 4 additions & 3 deletions src/idle.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ static uv_idle_t* luv_check_idle(lua_State* L, int index) {

static int luv_new_idle(lua_State* L) {
uv_idle_t* handle = lua_newuserdata(L, sizeof(*handle));
int ret = uv_idle_init(uv_default_loop(), handle);
int ret = uv_idle_init(luv_loop(L), handle);
if (ret < 0) {
lua_pop(L, 1);
return luv_error(L, ret);
Expand All @@ -34,9 +34,10 @@ static int luv_new_idle(lua_State* L) {
}

static void luv_idle_cb(uv_idle_t* handle) {
lua_State* L = luv_state(handle->loop);
luv_handle_t* data = handle->data;
luv_find_handle(R, data);
luv_call_callback(R, data, LUV_IDLE, 1);
luv_find_handle(L, data);
luv_call_callback(L, data, LUV_IDLE, 1);
}

static int luv_idle_start(lua_State* L) {
Expand Down

0 comments on commit 1521fa2

Please sign in to comment.