Neopallium / lua-zmq

Lua zeromq2 binding
http://github.com/Neopallium/lua-zmq
MIT License
151 stars 36 forks source link

lead to behavior is not correct #32

Closed qjzy2008 closed 11 years ago

qjzy2008 commented 12 years ago

please look at the code...


require("zmq");
local zmqContext = zmq.init(2);
local pullPipe = zmqContext:socket(zmq.PULL);

-- yes, this file is not exist, i want get error trace back info, but...
local name = "non_existent_qwertyuiop"; 
function testRequire()
  require(name);
end

function func1()
  local pipe = pullPipe; -- or print(pullPipe), any usage if reference pullPipe
end

testRequire();  -- require function will not correct , beacuse in func1()
Neopallium commented 11 years ago

Sorry for the late reply, I didn't notice that e-mail notices where disabled. Most likely got disabled when github changed how notices are handled (watched vs. starred).

The reason for the hang is that the zmq context is GC'ed when there are still an open zmq sockets in that context. 'func1' is a global and therefor keeps a reference to the pullPipe socket alive.

When the Lua VM catches an error thrown from the main script, it will do a Full GC before printing the error and exiting.

A work around for this is to store the zmq context in a global to keep it alive:

local zmq = require"zmq"
local ctx = zmq.init(1)

-- global ref to socket.
pullPipe = ctx:socket(zmq.PULL)

-- for testing:
if arg[1] == '-ctx' then
    -- keep context alive, too.
    zmq.ctx = ctx
end

-- some code that throws an error
error("test Full GC when error thrown from Main script.")

-- normal exit
pullPipe:close()
ctx:term()

There is no way to know if zmq_term() will block because of open sockets, nor is there a simple way track the creation/destruction of zmq sockets for a context, since the context can be shared between threads.