Comparison

net/cqueues.lua @ 6537:e4d443d05626

net.cqueues: Fixes hardcoded timeout for first iteration This was originally put in place as a fix for what ended up a cqueues bug: https://github.com/wahern/cqueues/issues/40 A check for a cqueues version with the bug fix is included.
author daurnimator <quae@daurnimator.com>
date Tue, 13 Jan 2015 18:36:00 -0500
parent 6536:605a87e90e27
child 6538:f1eb66288f60
comparison
equal deleted inserted replaced
6536:605a87e90e27 6537:e4d443d05626
7 -- This module allows you to use cqueues with a net.server mainloop 7 -- This module allows you to use cqueues with a net.server mainloop
8 -- 8 --
9 9
10 local server = require "net.server"; 10 local server = require "net.server";
11 local cqueues = require "cqueues"; 11 local cqueues = require "cqueues";
12 assert(cqueues.VERSION >= 20150112, "cqueues newer than 20151013 required")
12 13
13 -- Create a single top level cqueue 14 -- Create a single top level cqueue
14 local cq; 15 local cq;
15 16
16 if server.cq then -- server provides cqueues object 17 if server.cq then -- server provides cqueues object
41 end); 42 end);
42 elseif server.event and server.base then -- server_event 43 elseif server.event and server.base then -- server_event
43 cq = cqueues.new(); 44 cq = cqueues.new();
44 -- Only need to listen for readable; cqueues handles everything under the hood 45 -- Only need to listen for readable; cqueues handles everything under the hood
45 local EV_READ = server.event.EV_READ; 46 local EV_READ = server.event.EV_READ;
47 -- Convert a cqueues timeout to an acceptable timeout for luaevent
48 local function luaevent_safe_timeout(cq)
49 local t = cq:timeout();
50 -- if you give luaevent 0 or nil, it re-uses the previous timeout.
51 if t == 0 then
52 t = 0.000001; -- 1 microsecond is the smallest that works (goes into a `struct timeval`)
53 elseif t == nil then -- pick something big if we don't have one
54 t = 0x7FFFFFFF; -- largest 32bit int
55 end
56 return t
57 end
46 local event_handle; 58 local event_handle;
47 event_handle = server.base:addevent(cq:pollfd(), EV_READ, function(e) 59 event_handle = server.base:addevent(cq:pollfd(), EV_READ, function(e)
48 -- Need to reference event_handle or this callback will get collected 60 -- Need to reference event_handle or this callback will get collected
49 -- This creates a circular reference that can only be broken if event_handle is manually :close()'d 61 -- This creates a circular reference that can only be broken if event_handle is manually :close()'d
50 local _ = event_handle; 62 local _ = event_handle;
63 -- Run as many cqueues things as possible (with a timeout of 0)
64 -- If an error is thrown, it will break the libevent loop; but prosody resumes after logging a top level error
51 assert(cq:loop(0)); 65 assert(cq:loop(0));
52 -- Convert a cq timeout to an acceptable timeout for luaevent 66 return EV_READ, luaevent_safe_timeout(cq);
53 local t = cq:timeout(); 67 end, luaevent_safe_timeout(cq));
54 if t == 0 then -- if you give luaevent 0, it won't call this callback again
55 t = 0.000001; -- 1 microsecond is the smallest that works (goes into a `struct timeval`)
56 elseif t == nil then -- you always need to give a timeout, pick something big if we don't have one
57 t = 0x7FFFFFFF; -- largest 32bit int
58 end
59 return EV_READ, t;
60 end,
61 -- Schedule the callback to fire on first tick to ensure any cq:wrap calls that happen during start-up are serviced.
62 0.000001);
63 else 68 else
64 error "NYI" 69 error "NYI"
65 end 70 end
66 71
67 return { 72 return {