Skip to content

Commit

Permalink
Enhance error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
javalikescript committed Nov 24, 2024
1 parent 98e8fa9 commit 7f4f31f
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 26 deletions.
48 changes: 29 additions & 19 deletions src/async.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,16 @@ static luv_async_send_t* luv_async_pop(luv_async_arg_t* asarg) {

static luv_async_send_t* luv_async_push(luv_async_arg_t* asarg) {
luv_async_send_t* sendarg = (luv_async_send_t*)malloc(sizeof(luv_async_send_t));
memset(sendarg, 0, sizeof(luv_async_send_t));
asarg->count++;
if (asarg->last != NULL) {
asarg->last->next = sendarg;
}
asarg->last = sendarg;
if (asarg->first == NULL) {
asarg->first = sendarg;
if (sendarg != NULL) {
memset(sendarg, 0, sizeof(luv_async_send_t));
asarg->count++;
if (asarg->last != NULL) {
asarg->last->next = sendarg;
}
asarg->last = sendarg;
if (asarg->first == NULL) {
asarg->first = sendarg;
}
}
return sendarg;
}
Expand Down Expand Up @@ -154,25 +156,33 @@ static int luv_async_send(lua_State* L) {
uv_async_t* handle = luv_check_async(L, 1);
luv_async_arg_t* asarg = luv_get_async_arg_from_handle(handle);
uv_mutex_t *argmutex = &asarg->mutex;
luv_thread_arg_t* args;
int n;
luv_thread_arg_t targcpy;
ret = luv_thread_arg_set(L, &targcpy, 2, lua_gettop(L), LUVF_THREAD_MODE_ASYNC|LUVF_THREAD_SIDE_CHILD);
if (ret < 0) {
luv_thread_arg_free(&targcpy);
return luv_thread_arg_error(L);
}
uv_mutex_lock(argmutex);
if (luv_is_async_queue(asarg)) {
if (asarg->count >= asarg->max) {
luv_async_send_t* sendarg = NULL;
ret = UV_ENOSPC;
if (asarg->count < asarg->max) {
sendarg = luv_async_push(asarg);
if (sendarg == NULL) {
ret = UV_ENOMEM;
}
}
if (sendarg == NULL) {
uv_mutex_unlock(argmutex);
return luv_error(L, UV_ENOSPC);
luv_thread_arg_free(&targcpy);
return luv_error(L, ret);
}
luv_async_send_t* sendarg = luv_async_push(asarg);
args = &sendarg->targ;
sendarg->targ = targcpy;
} else {
luv_thread_arg_free(&asarg->targ); // in case of a pending send
args = &asarg->targ;
asarg->targ = targcpy;
}
n = luv_thread_arg_set(L, args, 2, lua_gettop(L), LUVF_THREAD_MODE_ASYNC|LUVF_THREAD_SIDE_CHILD);
uv_mutex_unlock(argmutex);
if (n < 0) {
return luv_thread_arg_error(L);
}
ret = uv_async_send(handle);
return luv_result(L, ret);
}
Expand Down
27 changes: 22 additions & 5 deletions src/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ static const char* luv_getmtname(lua_State *L, int idx) {
return name;
}

static int luv_thread_arg_set_error(lua_State* L, luv_thread_arg_t* args, int type, int index) {
args->argc = index;
lua_pushinteger(L, type);
lua_pushinteger(L, index + 1);
return -1;
}

static int luv_thread_arg_set(lua_State* L, luv_thread_arg_t* args, int idx, int top, int flags) {
int i;
int side = LUVF_THREAD_SIDE(flags);
Expand All @@ -72,7 +79,8 @@ static int luv_thread_arg_set(lua_State* L, luv_thread_arg_t* args, int idx, int
args->flags = flags;
while (i <= top && i < LUV_THREAD_MAXNUM_ARG + idx)
{
luv_val_t *arg = args->argv + (i - idx);
int ii = i - idx;
luv_val_t *arg = args->argv + ii;
arg->type = lua_type(L, i);
arg->ref[0] = arg->ref[1] = LUA_NOREF;
switch (arg->type)
Expand All @@ -95,6 +103,9 @@ static int luv_thread_arg_set(lua_State* L, luv_thread_arg_t* args, int idx, int
size_t l = 0;
const char* p = lua_tolstring(L, i, &l);
void* b = malloc(l + 1);
if (b == NULL) {
return luv_thread_arg_set_error(L, args, LUA_TNONE, ii);
}
arg->val.str.base = memcpy((void*)b, p, l + 1);
arg->val.str.len = l;
} else {
Expand All @@ -111,11 +122,17 @@ static int luv_thread_arg_set(lua_State* L, luv_thread_arg_t* args, int idx, int
if (async) {
if (l > 0) {
void* b = malloc(l);
if (b == NULL) {
return luv_thread_arg_set_error(L, args, LUA_TNONE, ii);
}
p = (const void*)memcpy(b, p, l);
}
if (mtname != NULL) {
size_t ml = strlen(mtname) + 1;
char* b = malloc(ml);
if (b == NULL) {
return luv_thread_arg_set_error(L, args, LUA_TNONE, ii);
}
mtname = (const void*)memcpy(b, mtname, ml);
}
} else {
Expand All @@ -128,10 +145,7 @@ static int luv_thread_arg_set(lua_State* L, luv_thread_arg_t* args, int idx, int
}
break;
default:
args->argc = i - idx;
lua_pushinteger(L, arg->type);
lua_pushinteger(L, i - idx + 1);
return -1;
return luv_thread_arg_set_error(L, args, arg->type, ii);
}
i++;
}
Expand Down Expand Up @@ -251,6 +265,9 @@ static int luv_thread_arg_error(lua_State *L) {
int type = lua_tointeger(L, -2);
int pos = lua_tointeger(L, -1);
lua_pop(L, 2);
if (type == LUA_TNONE) {
return luaL_error(L, "Error: thread arg failure at %d", pos);
}
return luaL_error(L, "Error: thread arg not support type '%s' at %d",
lua_typename(L, type), pos);
}
Expand Down
5 changes: 3 additions & 2 deletions tests/test-async.lua
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ return require('lib/tap')(function (test)
end))
uv.new_thread(function(asy)
assert(type(asy)=='userdata')
assert(asy:send('not ok')==0) -- will be ignored but its ok
assert(asy:send('not ok')==0) -- will be ignored but it's ok
assert(asy:send('ok')==0)
require('luv').sleep(10)
end, async):join()
Expand Down Expand Up @@ -62,8 +62,9 @@ return require('lib/tap')(function (test)
assert(v=='ok')
async:close()
end))
assert(async:send('not ok')==0) -- will be ignored but its ok
assert(async:send('not ok')==0) -- will be ignored but it's ok
assert(async:send('ok')==0)
assert(pcall(uv.async_send, 'not ok', function() end)==false) -- will fail
uv.run()
end)

Expand Down

0 comments on commit 7f4f31f

Please sign in to comment.