Closed houseofkodai closed 10 years ago
The issue is the slightly non intuitive iterator interface of epoll_wait (and some other similar functions). Maybe I should change this, but I am not sure how best to. The following works:
local S = require 'syscall'
local ep = S.epoll_create()
ep:epoll_ctl('add', 0, 'in') --stdin
local epevents = S.t.epoll_events(2)
local epwait = function(timeout) return ep:epoll_wait(epevents, timeout) end
while true do
local f, a, r = epwait()
if f then
for i,evnt in f, a, r do
if evnt.IN then io.read() end
end
else print(a) end
end
The issue is if epoll_wait gets an error it returns nil, error (like all other syscalls do), but this is not a valid iterator (which must start with a function, hence the calling nil). You could wrap it to return an iterator that just terminates if you dont really care about errors, like this:
local S = require 'syscall'
local ep = S.epoll_create()
ep:epoll_ctl('add', 0, 'in') --stdin
local epevents = S.t.epoll_events(2)
local epwait = function(timeout)
local function nilf() return nil end
local f, a, r = ep:epoll_wait(epevents, timeout)
if f then return f, a, r else return nilf end
end
while true do
for i,evnt in epwait() do
if evnt.IN then io.read() end
end
end
Thanks for the prompt response - this works.
Yes the iterator logic is a bit confusing; but the lack of sample code made discovering its' proper usage more difficult.
May I suggest that this logic be used in the sample/testing code (epoll.lua) - which is what I referred to first, and I'm guessing that others would too. of course, the next thing I did was search the issues and posted this, since I did not find something similar.
when SIGSTOP CTRL+Z is given to a running program and SIGCONT (bg/fg) is given - epoll_wait goes for a toss - groks with "attempt to call a nil value"
replicable by running the following code - hitting CTRL+Z and then bg/fg from shell