Skip to content

Commit

Permalink
Merge pull request #223 from luvit/fix-string-gc-in-fs-write
Browse files Browse the repository at this point in the history
luv_fs: fix gc of string during a fs.write
  • Loading branch information
philips committed May 16, 2012
2 parents 5befa91 + eba20e7 commit 7aa587c
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 11 deletions.
44 changes: 34 additions & 10 deletions src/luv_fs.c
Expand Up @@ -176,8 +176,12 @@ void luv_after_fs(uv_fs_t* req) {
luv_fs_ref_t* ref = req->data;
lua_State *L = ref->L;
int argc;
lua_rawgeti(L, LUA_REGISTRYINDEX, ref->r);
luaL_unref(L, LUA_REGISTRYINDEX, ref->r);

lua_rawgeti(L, LUA_REGISTRYINDEX, ref->rstr);
luaL_unref(L, LUA_REGISTRYINDEX, ref->rstr);

lua_rawgeti(L, LUA_REGISTRYINDEX, ref->rcb);
luaL_unref(L, LUA_REGISTRYINDEX, ref->rcb);

argc = luv_process_fs_result(L, req);

Expand All @@ -187,16 +191,33 @@ void luv_after_fs(uv_fs_t* req) {
free(ref); /* We're done with the ref object, free it */
}

/* Utility for storing the callback in the fs_req token */
uv_fs_t* luv_fs_store_callback(lua_State* L, int index) {

static luv_fs_ref_t* luv_fs_ref_alloc(lua_State* L) {
luv_fs_ref_t* ref = malloc(sizeof(luv_fs_ref_t));
ref->L = L;
if (lua_isfunction(L, index)) {
lua_pushvalue(L, index); /* Store the callback */
ref->r = luaL_ref(L, LUA_REGISTRYINDEX);
}
ref->fs_req.data = ref;
ref->rcb = LUA_NOREF;
ref->rstr = LUA_NOREF;
return ref;
}

static void luv_fs_ref_callback(luv_fs_ref_t* ref, int index) {
if (lua_isfunction(ref->L, index)) {
lua_pushvalue(ref->L, index); /* Store the callback */
ref->rcb = luaL_ref(ref->L, LUA_REGISTRYINDEX);
}
}

static void luv_fs_ref_string(luv_fs_ref_t* ref, int index) {
if (lua_isstring(ref->L, index)) {
lua_pushvalue(ref->L, index);
ref->rstr = luaL_ref(ref->L, LUA_REGISTRYINDEX);
}
}

/* Utility for storing the callback in the fs_req token */
uv_fs_t* luv_fs_store_callback(lua_State* L, int index) {
luv_fs_ref_t* ref = luv_fs_ref_alloc(L);
luv_fs_ref_callback(ref, index);
return &ref->fs_req;
}

Expand Down Expand Up @@ -258,7 +279,10 @@ int luv_fs_write(lua_State* L) {
off_t offset = luaL_checkint(L, 2);
size_t length;
void* chunk = (void*)luaL_checklstring(L, 3, &length);
uv_fs_t* req = luv_fs_store_callback(L, 4);
luv_fs_ref_t* ref = luv_fs_ref_alloc(L);
luv_fs_ref_string(ref, 3);
luv_fs_ref_callback(ref, 4);
uv_fs_t* req = &ref->fs_req;
FS_CALL(write, 4, NULL, file, chunk, length, offset);
}

Expand Down
3 changes: 2 additions & 1 deletion src/luv_fs.h
Expand Up @@ -62,7 +62,8 @@ int luv_fs_fchown(lua_State* L);

typedef struct {
lua_State* L;
int r;
int rcb; /* callback ref */
int rstr; /* string ref */
uv_fs_t fs_req;
void* buf;
} luv_fs_ref_t;
Expand Down

0 comments on commit 7aa587c

Please sign in to comment.