Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

remove gettop() and assert, add a test case that create a socket hand…

…le in fiber.
  • Loading branch information...
commit f36c77ef31b32e2ee2b0d1b51466e739073c3ad0 1 parent 93ab775
@AndrewTsao AndrewTsao authored
Showing with 56 additions and 3 deletions.
  1. +0 −2  src/utils.c
  2. +7 −1 src/utils.h
  3. +49 −0 tests/test-fiber-bug319.lua
View
2  src/utils.c
@@ -180,7 +180,6 @@ uv_loop_t* luv_get_loop(lua_State *L) {
/* Initialize a new lhandle and push the new userdata on the stack. */
luv_handle_t* luv_handle_create(lua_State* L, size_t size, const char* type) {
- int before = lua_gettop(L);
lua_State* mainthread;
/* Create the userdata and set it's metatable */
luv_handle_t* lhandle = (luv_handle_t*)lua_newuserdata(L, sizeof(luv_handle_t));
@@ -209,7 +208,6 @@ luv_handle_t* luv_handle_create(lua_State* L, size_t size, const char* type) {
}
lhandle->ref = LUA_NOREF;
lhandle->type = type;
- assert(before + 1 == lua_gettop(L));
return lhandle;
}
View
8 src/utils.h
@@ -59,7 +59,13 @@ typedef struct {
uv_handle_t* handle; /* The actual uv handle. memory managed by luv */
int refCount; /* a count of all pending request to know strength */
lua_State* L; /* L and ref together form a reference to the userdata */
- int threadref; /* L is always `mainthread, threadref in `mainthread */
+ int threadref; /* if handle is created in a coroutine(not main thread), threadref is
+ the reference to the coroutine in the Lua registery.
+ we release the reference when handle closed.
+ if handle is created in the main thread, threadref is LUA_NOREF.
+ we must hold the coroutine, because in some cases(see issue #319) that the coroutine
+ referenced by nothing and would collected by gc, then uv's callback touch an
+ invalid pointer. */
int ref; /* ref is null when refCount is 0 meaning we're weak */
const char* type;
} luv_handle_t;
View
49 tests/test-fiber-bug319.lua
@@ -28,8 +28,57 @@ fiber.new(function(wrap, wait)
end)
end
end)
+
collectgarbage()
+local net = require('net')
+local PORT = process.env.PORT or 10082
+local messages = {'a','b','c'}
+
+fiber.new(function(wrap, wait)
+ local server
+ server = net.createServer(function(client)
+ client:on("data", function(data)
+ fiber.new(function(wrap, wait)
+ for _, message in ipairs(messages) do
+ wait(function(resume)
+ client:write(message, function(err)
+ timer.setTimeout(1, resume)
+ end)
+ end)
+ end
+ client:destroy()
+ server:close()
+ end)
+ end)
+ end)
+ server:listen(PORT, "127.0.0.1")
+ server:on("error", function(err)
+ assert(false)
+ end)
+ wait(function(resume) process.nextTick(resume) end)
+end)
+collectgarbage()
+
+local client = require("uv").Tcp:new()
+client:connect("127.0.0.1", PORT)
+client:on("connect", function()
+ client:write("hi")
+ local received = {}
+ client:on("data", function(data)
+ received[#received+1] = data
+ if data == "3:c" then
+ client:close()
+ assert(received[1] == messages[1])
+ assert(received[2] == messages[2])
+ assert(received[3] == messages[3])
+ end
+ end)
+end)
+client:on("error", function()
+ assert(false)
+end)
+
process:on('exit', function()
assert(count == 10)
end)
Please sign in to comment.
Something went wrong with that request. Please try again.