author | Kim Alvefur <zash@zash.se> |
Mon, 25 Nov 2019 23:51:41 +0100 | |
changeset 10452 | cbe524ed1a6a |
parent 6541 | f1eb66288f60 |
child 11000 | d742095046f9 |
permissions | -rw-r--r-- |
6517
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
1 |
-- Prosody IM |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
2 |
-- Copyright (C) 2014 Daurnimator |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
3 |
-- |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
4 |
-- This project is MIT/X11 licensed. Please see the |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
5 |
-- COPYING file in the source package for more information. |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
6 |
-- |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
7 |
-- This module allows you to use cqueues with a net.server mainloop |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
8 |
-- |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
9 |
|
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
10 |
local server = require "net.server"; |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
11 |
local cqueues = require "cqueues"; |
6541
f1eb66288f60
net.cqueues: Fix incorrect version check
daurnimator <quae@daurnimator.com>
parents:
6540
diff
changeset
|
12 |
assert(cqueues.VERSION >= 20150113, "cqueues newer than 20150113 required") |
6517
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
13 |
|
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
14 |
-- Create a single top level cqueue |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
15 |
local cq; |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
16 |
|
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
17 |
if server.cq then -- server provides cqueues object |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
18 |
cq = server.cq; |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
19 |
elseif server.get_backend() == "select" and server._addtimer then -- server_select |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
20 |
cq = cqueues.new(); |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
21 |
local function step() |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
22 |
assert(cq:loop(0)); |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
23 |
end |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
24 |
|
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
25 |
-- Use wrapclient (as wrapconnection isn't exported) to get server_select to watch cq fd |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
26 |
local handler = server.wrapclient({ |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
27 |
getfd = function() return cq:pollfd(); end; |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
28 |
settimeout = function() end; -- Method just needs to exist |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
29 |
close = function() end; -- Need close method for 'closeall' |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
30 |
}, nil, nil, {}); |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
31 |
|
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
32 |
-- Only need to listen for readable; cqueues handles everything under the hood |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
33 |
-- readbuffer is called when `select` notes an fd as readable |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
34 |
handler.readbuffer = step; |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
35 |
|
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
36 |
-- Use server_select low lever timer facility, |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
37 |
-- this callback gets called *every* time there is a timeout in the main loop |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
38 |
server._addtimer(function(current_time) |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
39 |
-- This may end up in extra step()'s, but cqueues handles it for us. |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
40 |
step(); |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
41 |
return cq:timeout(); |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
42 |
end); |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
43 |
elseif server.event and server.base then -- server_event |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
44 |
cq = cqueues.new(); |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
45 |
-- Only need to listen for readable; cqueues handles everything under the hood |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
46 |
local EV_READ = server.event.EV_READ; |
6540
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6539
diff
changeset
|
47 |
-- Convert a cqueues timeout to an acceptable timeout for luaevent |
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6539
diff
changeset
|
48 |
local function luaevent_safe_timeout(cq) |
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6539
diff
changeset
|
49 |
local t = cq:timeout(); |
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6539
diff
changeset
|
50 |
-- if you give luaevent 0 or nil, it re-uses the previous timeout. |
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6539
diff
changeset
|
51 |
if t == 0 then |
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6539
diff
changeset
|
52 |
t = 0.000001; -- 1 microsecond is the smallest that works (goes into a `struct timeval`) |
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6539
diff
changeset
|
53 |
elseif t == nil then -- pick something big if we don't have one |
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6539
diff
changeset
|
54 |
t = 0x7FFFFFFF; -- largest 32bit int |
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6539
diff
changeset
|
55 |
end |
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6539
diff
changeset
|
56 |
return t |
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6539
diff
changeset
|
57 |
end |
6539
605a87e90e27
net.cqueues: Add workaround for luaevent callback getting collected
daurnimator <quae@daurnimator.com>
parents:
6517
diff
changeset
|
58 |
local event_handle; |
605a87e90e27
net.cqueues: Add workaround for luaevent callback getting collected
daurnimator <quae@daurnimator.com>
parents:
6517
diff
changeset
|
59 |
event_handle = server.base:addevent(cq:pollfd(), EV_READ, function(e) |
605a87e90e27
net.cqueues: Add workaround for luaevent callback getting collected
daurnimator <quae@daurnimator.com>
parents:
6517
diff
changeset
|
60 |
-- Need to reference event_handle or this callback will get collected |
605a87e90e27
net.cqueues: Add workaround for luaevent callback getting collected
daurnimator <quae@daurnimator.com>
parents:
6517
diff
changeset
|
61 |
-- This creates a circular reference that can only be broken if event_handle is manually :close()'d |
605a87e90e27
net.cqueues: Add workaround for luaevent callback getting collected
daurnimator <quae@daurnimator.com>
parents:
6517
diff
changeset
|
62 |
local _ = event_handle; |
6540
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6539
diff
changeset
|
63 |
-- Run as many cqueues things as possible (with a timeout of 0) |
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6539
diff
changeset
|
64 |
-- If an error is thrown, it will break the libevent loop; but prosody resumes after logging a top level error |
6517
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
65 |
assert(cq:loop(0)); |
6540
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6539
diff
changeset
|
66 |
return EV_READ, luaevent_safe_timeout(cq); |
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6539
diff
changeset
|
67 |
end, luaevent_safe_timeout(cq)); |
6517
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
68 |
else |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
69 |
error "NYI" |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
70 |
end |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
71 |
|
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
72 |
return { |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
73 |
cq = cq; |
d425fc41e59f
net.cqueues: Add module that allows use of cqueues while still using net.server as main loop
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
74 |
} |