Software /
code /
prosody
Annotate
net/cqueues.lua @ 10704:06307833684b
Merge 0.11->trunk
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sun, 29 Mar 2020 22:12:42 +0200 |
parent | 6538:f1eb66288f60 |
child | 10996:d742095046f9 |
rev | line source |
---|---|
6514
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"; |
6538
f1eb66288f60
net.cqueues: Fix incorrect version check
daurnimator <quae@daurnimator.com>
parents:
6537
diff
changeset
|
12 assert(cqueues.VERSION >= 20150113, "cqueues newer than 20150113 required") |
6514
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; |
6537
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6536
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:
6536
diff
changeset
|
48 local function luaevent_safe_timeout(cq) |
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6536
diff
changeset
|
49 local t = cq:timeout(); |
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6536
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:
6536
diff
changeset
|
51 if t == 0 then |
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6536
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:
6536
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:
6536
diff
changeset
|
54 t = 0x7FFFFFFF; -- largest 32bit int |
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6536
diff
changeset
|
55 end |
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6536
diff
changeset
|
56 return t |
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6536
diff
changeset
|
57 end |
6536
605a87e90e27
net.cqueues: Add workaround for luaevent callback getting collected
daurnimator <quae@daurnimator.com>
parents:
6514
diff
changeset
|
58 local event_handle; |
605a87e90e27
net.cqueues: Add workaround for luaevent callback getting collected
daurnimator <quae@daurnimator.com>
parents:
6514
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:
6514
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:
6514
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:
6514
diff
changeset
|
62 local _ = event_handle; |
6537
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6536
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:
6536
diff
changeset
|
64 -- If an error is thrown, it will break the libevent loop; but prosody resumes after logging a top level error |
6514
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)); |
6537
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6536
diff
changeset
|
66 return EV_READ, luaevent_safe_timeout(cq); |
e4d443d05626
net.cqueues: Fixes hardcoded timeout for first iteration
daurnimator <quae@daurnimator.com>
parents:
6536
diff
changeset
|
67 end, luaevent_safe_timeout(cq)); |
6514
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 } |