diff options
author | Daniel Silverstone <dsilvers@digital-scurf.org> | 2012-02-04 02:15:25 +0900 |
---|---|---|
committer | Daniel Silverstone <dsilvers@digital-scurf.org> | 2012-02-04 02:15:25 +0900 |
commit | 130c133f0895ee56305a6bf0e686a0cc6127fdba (patch) | |
tree | 1eb3ae5bb8b395076df472ce8ff08c11280abf80 /luxio/event.lua | |
parent | bff5b824ff297b446cf1a0227c4e9f9b8b228f09 (diff) | |
download | luxio-130c133f0895ee56305a6bf0e686a0cc6127fdba.tar.gz |
Support simple handles in event library, and fix loads of bugs
Diffstat (limited to 'luxio/event.lua')
-rw-r--r-- | luxio/event.lua | 64 |
1 files changed, 45 insertions, 19 deletions
diff --git a/luxio/event.lua b/luxio/event.lua index b21b088..b47cba1 100644 --- a/luxio/event.lua +++ b/luxio/event.lua @@ -126,10 +126,16 @@ local function _claim_free_slot() return #pfds - (extend_by - 1) end -local function _set_events(fd, input_enable, output_enable) +local function _set_events(_fd, input_enable, output_enable) + local fd = _fd + if type(_fd) == "table" then + fd = _fd.fd + end local fdt = fds[fd] - assert(fdt, "File descriptor " .. tostring(fd) .. " is not registered") + assert(fdt, "File descriptor '" .. tostring(_fd) .. "' is not registered") + local events = fdt.events + if input_enable then events = bor(events, input_bits) elseif input_enable == false then @@ -141,13 +147,19 @@ local function _set_events(fd, input_enable, output_enable) events = bclear(events, POLLOUT) end pollfds_setslot(pfds, fds[fd].slotnr, fd, events, 0) + fdt.events = events end local function _null_evt() end -local function _register_fd(fd, ctx, input_evt, output_evt, error_evt) - assert(fds[fd] == nil, "File descriptor " .. tostring(fd) .. " is already registered") +local function _register_fd(_fd, ctx, input_evt, output_evt, error_evt) + local fd = _fd + if type(_fd) == "table" then + fd = _fd.fd + end + assert(fds[fd] == nil, "File descriptor '" .. tostring(_fd) .. "' is already registered") local fdt = { fd = fd, + _fd = _fd, ctx = ctx, input_evt = input_evt or _null_evt, output_evt = output_evt or _null_evt, @@ -156,16 +168,29 @@ local function _register_fd(fd, ctx, input_evt, output_evt, error_evt) events = 0 } fds[fd] = fdt - _set_events(fd) + _set_events(_fd) end -local function _unregister_fd(fd) +local function rpcall(...) + local t = {pcall(...)} + if not t[1] then + print("Error during event handling:", t[2]) + end + return unpack(t) +end +-- Uncomment this to disable error reporting +-- rpcall = pcall + +local function _unregister_fd(_fd) + if type(_fd) == "table" then + fd = _fd.fd + end local fdt = fds[fd] - assert(fdt, "File descriptor " .. tostring(fd) .. " is not registered") + assert(fdt, "File descriptor '" .. tostring(_fd) .. "' is not registered") -- pull this fd out of poll - pollfds_setslot(fdt.slotnr, -1, 0, 0) + pollfds_setslot(pfds, fdt.slotnr, -1, 0, 0) -- hand the slot back to the gap tracker - gaps[slotnr] = true + gaps[fdt.slotnr] = true -- and unregister the fd from the list fds[fd] = nil end @@ -182,21 +207,22 @@ local function _step(timeout) end local fd, ev, rev = pollfds_getslot(pfds, slot) local fdt = fds[fd] + local cev = 0 if fd >= 0 and rev ~= 0 then -- Deal with errors first local did_error = false if btest(rev, POLLNVAL) then -- fd is invalid, let the caller know did_error = true - pcall(fdt.error_evt, fdt.ctx, fd, _nval) + rpcall(fdt.error_evt, fdt.ctx, fd, _nval) elseif btest(rev, POLLERR) then -- fd errored did_error = true - pcall(fdt.error_evt, fdt.ctx, fd, _err) + rpcall(fdt.error_evt, fdt.ctx, fd, _err) elseif btest(rev, POLLHUP) then -- fd HUPped did_error = true - pcall(fdt.error_evt, fdt.ctx, fd, _hup) + rpcall(fdt.error_evt, fdt.ctx, fd, _hup) end if did_error then if fds[fd] then @@ -205,28 +231,28 @@ local function _step(timeout) else -- No error, process incoming data first. if btest(rev, POLLPRI) then - local ok, want = pcall(fdt.input_evt, fdt.ctx, fd, true) + local ok, want = rpcall(fdt.input_evt, fdt.ctx, fdt._fd, true) if ok and not want then - ev = bclear(ev, input_bits) + cev = bor(cev, input_bits) end elseif btest(rev, POLLIN) then - local ok, want = pcall(fdt.input_evt, fdt.ctx, fd, false) + local ok, want = rpcall(fdt.input_evt, fdt.ctx, fdt._fd, false) if ok and not want then - ev = bclear(ev, input_bits) + cev = bor(cev, input_bits) end end -- Now if we're still registered, process write space if fds[fd] and btest(rev, POLLOUT) then - local ok, want = pcall(fdt.output_evt, fdt.ctx, fd) + local ok, want = rpcall(fdt.output_evt, fdt.ctx, fdt._fd) if ok and not want then - ev = bclear(ev, POLLOUT) + cev = bor(cev, POLLOUT) end end end fds_to_process = fds_to_process - 1 if fds[fd] then -- rearm appropriate events - pollfds_setslot(pfds, slot, fd, ev, 0); + pollfds_setslot(pfds, slot, fd, bclear(fds[fd].events, cev), 0); end end end |