Software /
code /
prosody
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 { |