Software / code / prosody
Annotate
util/events.lua @ 13652:a08065207ef0
net.server_epoll: Call :shutdown() on TLS sockets when supported
Comment from Matthew:
This fixes a potential issue where the Prosody process gets blocked on sockets
waiting for them to close. Unlike non-TLS sockets, closing a TLS socket sends
layer 7 data, and this can cause problems for sockets which are in the process
of being cleaned up.
This depends on LuaSec changes which are not yet upstream.
From Martijn's original email:
So first my analysis of luasec. in ssl.c the socket is put into blocking
mode right before calling SSL_shutdown() inside meth_destroy(). My best
guess to why this is is because meth_destroy is linked to the __close
and __gc methods, which can't exactly be called multiple times and
luasec does want to make sure that a tls session is shutdown as clean
as possible.
I can't say I disagree with this reasoning and don't want to change this
behaviour. My solution to this without changing the current behaviour is
to introduce a shutdown() method. I am aware that this overlaps in a
conflicting way with tcp's shutdown method, but it stays close to the
OpenSSL name. This method calls SSL_shutdown() in the current
(non)blocking mode of the underlying socket and returns a boolean
whether or not the shutdown is completed (matching SSL_shutdown()'s 0
or 1 return values), and returns the familiar ssl_ioerror() strings on
error with a false for completion. This error can then be used to
determine if we have wantread/wantwrite to finalize things. Once
meth_shutdown() has been called once a shutdown flag will be set, which
indicates to meth_destroy() that the SSL_shutdown() has been handled
by the application and it shouldn't be needed to set the socket to
blocking mode. I've left the SSL_shutdown() call in the
LSEC_STATE_CONNECTED to prevent TOCTOU if the application reaches a
timeout for the shutdown code, which might allow SSL_shutdown() to
clean up anyway at the last possible moment.
Another thing I've changed to luasec is the call to socket_setblocking()
right before calling close(2) in socket_destroy() in usocket.c.
According to the latest POSIX[0]:
Note that the requirement for close() on a socket to block for up to
the current linger interval is not conditional on the O_NONBLOCK
setting.
Which I read to mean that removing O_NONBLOCK on the socket before close
doesn't impact the behaviour and only causes noise in system call
tracers. I didn't touch the windows bits of this, since I don't do
windows.
For the prosody side of things I've made the TLS shutdown bits resemble
interface:onwritable(), and put it under a combined guard of self._tls
and self.conn.shutdown. The self._tls bit is there to prevent getting
stuck on this condition, and self.conn.shutdown is there to prevent the
code being called by instances where the patched luasec isn't deployed.
The destroy() method can be called from various places and is read by
me as the "we give up" error path. To accommodate for these unexpected
entrypoints I've added a single call to self.conn:shutdown() to prevent
the socket being put into blocking mode. I have no expectations that
there is any other use here. Same as previous, the self.conn.shutdown
check is there to make sure it's not called on unpatched luasec
deployments and self._tls is there to make sure we don't call shutdown()
on tcp sockets.
I wouldn't recommend logging of the conn:shutdown() error inside
close(), since a lot of clients simply close the connection before
SSL_shutdown() is done.
| author | Martijn van Duren <martijn@openbsd.org> |
|---|---|
| date | Thu, 06 Feb 2025 15:04:38 +0000 |
| parent | 11058:c99afee1c548 |
| rev | line source |
|---|---|
|
1522
569d58d21612
Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents:
1507
diff
changeset
|
1 -- Prosody IM |
|
2923
b7049746bd29
Update copyright headers for 2010
Matthew Wild <mwild1@gmail.com>
parents:
1522
diff
changeset
|
2 -- Copyright (C) 2008-2010 Matthew Wild |
|
b7049746bd29
Update copyright headers for 2010
Matthew Wild <mwild1@gmail.com>
parents:
1522
diff
changeset
|
3 -- Copyright (C) 2008-2010 Waqas Hussain |
|
5776
bd0ff8ae98a8
Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents:
5749
diff
changeset
|
4 -- |
|
1522
569d58d21612
Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents:
1507
diff
changeset
|
5 -- This project is MIT/X11 licensed. Please see the |
|
569d58d21612
Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents:
1507
diff
changeset
|
6 -- COPYING file in the source package for more information. |
|
569d58d21612
Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents:
1507
diff
changeset
|
7 -- |
|
569d58d21612
Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents:
1507
diff
changeset
|
8 |
|
1507
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
9 |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
10 local pairs = pairs; |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
11 local t_insert = table.insert; |
|
6648
999434eb1bbf
util.events: Add local reference to table.remove (fixes traceback)
Kim Alvefur <zash@zash.se>
parents:
6641
diff
changeset
|
12 local t_remove = table.remove; |
|
1507
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
13 local t_sort = table.sort; |
|
3501
90c18e0355af
util.events: Event handler indices are now built lazily (faster server startup for large number of hosts).
Waqas Hussain <waqas20@gmail.com>
parents:
3500
diff
changeset
|
14 local setmetatable = setmetatable; |
|
90c18e0355af
util.events: Event handler indices are now built lazily (faster server startup for large number of hosts).
Waqas Hussain <waqas20@gmail.com>
parents:
3500
diff
changeset
|
15 local next = next; |
|
1507
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
16 |
|
6777
5de6b93d0190
util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents:
6665
diff
changeset
|
17 local _ENV = nil; |
|
8555
4f0f5b49bb03
vairious: Add annotation when an empty environment is set [luacheck]
Kim Alvefur <zash@zash.se>
parents:
8382
diff
changeset
|
18 -- luacheck: std none |
|
1507
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
19 |
|
6777
5de6b93d0190
util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents:
6665
diff
changeset
|
20 local function new() |
|
7039
138241cc1b3a
util.events: Document data structures
Matthew Wild <mwild1@gmail.com>
parents:
6777
diff
changeset
|
21 -- Map event name to ordered list of handlers (lazily built): handlers[event_name] = array_of_handler_functions |
|
1507
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
22 local handlers = {}; |
|
7039
138241cc1b3a
util.events: Document data structures
Matthew Wild <mwild1@gmail.com>
parents:
6777
diff
changeset
|
23 -- Array of wrapper functions that wrap all events (nil if empty) |
|
6638
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
24 local global_wrappers; |
|
7039
138241cc1b3a
util.events: Document data structures
Matthew Wild <mwild1@gmail.com>
parents:
6777
diff
changeset
|
25 -- Per-event wrappers: wrappers[event_name] = wrapper_function |
|
6638
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
26 local wrappers = {}; |
|
7039
138241cc1b3a
util.events: Document data structures
Matthew Wild <mwild1@gmail.com>
parents:
6777
diff
changeset
|
27 -- Event map: event_map[handler_function] = priority_number |
|
1507
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
28 local event_map = {}; |
|
11058
c99afee1c548
util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents:
8759
diff
changeset
|
29 -- Debug hook, if any |
|
c99afee1c548
util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents:
8759
diff
changeset
|
30 local active_debug_hook = nil; |
|
7039
138241cc1b3a
util.events: Document data structures
Matthew Wild <mwild1@gmail.com>
parents:
6777
diff
changeset
|
31 -- Called on-demand to build handlers entries |
|
8382
e5d00bf4a4d5
util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents:
7424
diff
changeset
|
32 local function _rebuild_index(self, event) |
|
1507
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
33 local _handlers = event_map[event]; |
|
3501
90c18e0355af
util.events: Event handler indices are now built lazily (faster server startup for large number of hosts).
Waqas Hussain <waqas20@gmail.com>
parents:
3500
diff
changeset
|
34 if not _handlers or next(_handlers) == nil then return; end |
|
3500
a49ed9166820
util.events: Create new index on handler change instead of modifying existing one (this makes util.events fully reentrant).
Waqas Hussain <waqas20@gmail.com>
parents:
3499
diff
changeset
|
35 local index = {}; |
|
1507
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
36 for handler in pairs(_handlers) do |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
37 t_insert(index, handler); |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
38 end |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
39 t_sort(index, function(a, b) return _handlers[a] > _handlers[b]; end); |
|
8382
e5d00bf4a4d5
util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents:
7424
diff
changeset
|
40 self[event] = index; |
|
3501
90c18e0355af
util.events: Event handler indices are now built lazily (faster server startup for large number of hosts).
Waqas Hussain <waqas20@gmail.com>
parents:
3500
diff
changeset
|
41 return index; |
|
1507
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
42 end; |
|
3501
90c18e0355af
util.events: Event handler indices are now built lazily (faster server startup for large number of hosts).
Waqas Hussain <waqas20@gmail.com>
parents:
3500
diff
changeset
|
43 setmetatable(handlers, { __index = _rebuild_index }); |
|
1507
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
44 local function add_handler(event, handler, priority) |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
45 local map = event_map[event]; |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
46 if map then |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
47 map[handler] = priority or 0; |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
48 else |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
49 map = {[handler] = priority or 0}; |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
50 event_map[event] = map; |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
51 end |
|
3501
90c18e0355af
util.events: Event handler indices are now built lazily (faster server startup for large number of hosts).
Waqas Hussain <waqas20@gmail.com>
parents:
3500
diff
changeset
|
52 handlers[event] = nil; |
|
1507
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
53 end; |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
54 local function remove_handler(event, handler) |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
55 local map = event_map[event]; |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
56 if map then |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
57 map[handler] = nil; |
|
3501
90c18e0355af
util.events: Event handler indices are now built lazily (faster server startup for large number of hosts).
Waqas Hussain <waqas20@gmail.com>
parents:
3500
diff
changeset
|
58 handlers[event] = nil; |
|
3776
bc4f67a0658d
util.events: Remove an event's table when it has no more handlers.
Waqas Hussain <waqas20@gmail.com>
parents:
3501
diff
changeset
|
59 if next(map) == nil then |
|
bc4f67a0658d
util.events: Remove an event's table when it has no more handlers.
Waqas Hussain <waqas20@gmail.com>
parents:
3501
diff
changeset
|
60 event_map[event] = nil; |
|
bc4f67a0658d
util.events: Remove an event's table when it has no more handlers.
Waqas Hussain <waqas20@gmail.com>
parents:
3501
diff
changeset
|
61 end |
|
1507
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
62 end |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
63 end; |
|
6664
5466f24e51c9
util.events: Add get_handlers() method
Matthew Wild <mwild1@gmail.com>
parents:
6641
diff
changeset
|
64 local function get_handlers(event) |
|
5466f24e51c9
util.events: Add get_handlers() method
Matthew Wild <mwild1@gmail.com>
parents:
6641
diff
changeset
|
65 return handlers[event]; |
|
5466f24e51c9
util.events: Add get_handlers() method
Matthew Wild <mwild1@gmail.com>
parents:
6641
diff
changeset
|
66 end; |
|
8382
e5d00bf4a4d5
util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents:
7424
diff
changeset
|
67 local function add_handlers(self) |
|
e5d00bf4a4d5
util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents:
7424
diff
changeset
|
68 for event, handler in pairs(self) do |
|
1507
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
69 add_handler(event, handler); |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
70 end |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
71 end; |
|
8382
e5d00bf4a4d5
util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents:
7424
diff
changeset
|
72 local function remove_handlers(self) |
|
e5d00bf4a4d5
util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents:
7424
diff
changeset
|
73 for event, handler in pairs(self) do |
|
1507
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
74 remove_handler(event, handler); |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
75 end |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
76 end; |
|
6638
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
77 local function _fire_event(event_name, event_data) |
|
5749
60b3b6d27364
util.events: Remove varargs, event handlers can now only accept a single parameter
Matthew Wild <mwild1@gmail.com>
parents:
3776
diff
changeset
|
78 local h = handlers[event_name]; |
|
11058
c99afee1c548
util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents:
8759
diff
changeset
|
79 if h and not active_debug_hook then |
|
1507
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
80 for i=1,#h do |
|
5749
60b3b6d27364
util.events: Remove varargs, event handlers can now only accept a single parameter
Matthew Wild <mwild1@gmail.com>
parents:
3776
diff
changeset
|
81 local ret = h[i](event_data); |
|
1507
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
82 if ret ~= nil then return ret; end |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
83 end |
|
11058
c99afee1c548
util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents:
8759
diff
changeset
|
84 elseif h and active_debug_hook then |
|
c99afee1c548
util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents:
8759
diff
changeset
|
85 for i=1,#h do |
|
c99afee1c548
util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents:
8759
diff
changeset
|
86 local ret = active_debug_hook(h[i], event_name, event_data); |
|
c99afee1c548
util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents:
8759
diff
changeset
|
87 if ret ~= nil then return ret; end |
|
c99afee1c548
util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents:
8759
diff
changeset
|
88 end |
|
1507
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
89 end |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
90 end; |
|
6638
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
91 local function fire_event(event_name, event_data) |
|
8382
e5d00bf4a4d5
util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents:
7424
diff
changeset
|
92 -- luacheck: ignore 432/event_name 432/event_data |
|
6638
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
93 local w = wrappers[event_name] or global_wrappers; |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
94 if w then |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
95 local curr_wrapper = #w; |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
96 local function c(event_name, event_data) |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
97 curr_wrapper = curr_wrapper - 1; |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
98 if curr_wrapper == 0 then |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
99 if global_wrappers == nil or w == global_wrappers then |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
100 return _fire_event(event_name, event_data); |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
101 end |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
102 w, curr_wrapper = global_wrappers, #global_wrappers; |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
103 return w[curr_wrapper](c, event_name, event_data); |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
104 else |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
105 return w[curr_wrapper](c, event_name, event_data); |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
106 end |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
107 end |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
108 return w[curr_wrapper](c, event_name, event_data); |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
109 end |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
110 return _fire_event(event_name, event_data); |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
111 end |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
112 local function add_wrapper(event_name, wrapper) |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
113 local w; |
|
6641
b44ebfe81c73
util.events: Change from nil to false to indicate adding a global wrapper
Matthew Wild <mwild1@gmail.com>
parents:
6638
diff
changeset
|
114 if event_name == false then |
|
6638
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
115 w = global_wrappers; |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
116 if not w then |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
117 w = {}; |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
118 global_wrappers = w; |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
119 end |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
120 else |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
121 w = wrappers[event_name]; |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
122 if not w then |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
123 w = {}; |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
124 wrappers[event_name] = w; |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
125 end |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
126 end |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
127 w[#w+1] = wrapper; |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
128 end |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
129 local function remove_wrapper(event_name, wrapper) |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
130 local w; |
|
6641
b44ebfe81c73
util.events: Change from nil to false to indicate adding a global wrapper
Matthew Wild <mwild1@gmail.com>
parents:
6638
diff
changeset
|
131 if event_name == false then |
|
6638
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
132 w = global_wrappers; |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
133 else |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
134 w = wrappers[event_name]; |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
135 end |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
136 if not w then return; end |
|
8758
c380a22d52d5
util.events: Fix loop construct (negative step required)
Matthew Wild <mwild1@gmail.com>
parents:
7424
diff
changeset
|
137 for i = #w, 1, -1 do |
|
6638
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
138 if w[i] == wrapper then |
|
6648
999434eb1bbf
util.events: Add local reference to table.remove (fixes traceback)
Kim Alvefur <zash@zash.se>
parents:
6641
diff
changeset
|
139 t_remove(w, i); |
|
6638
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
140 end |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
141 end |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
142 if #w == 0 then |
|
7424
ba83ff7d9bd7
util.events: Fix comparison of event_name with nil instead of false (fixes #554)
Matthew Wild <mwild1@gmail.com>
parents:
7039
diff
changeset
|
143 if event_name == false then |
|
6638
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
144 global_wrappers = nil; |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
145 else |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
146 wrappers[event_name] = nil; |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
147 end |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
148 end |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
149 end |
|
11058
c99afee1c548
util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents:
8759
diff
changeset
|
150 |
|
c99afee1c548
util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents:
8759
diff
changeset
|
151 local function set_debug_hook(new_hook) |
|
c99afee1c548
util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents:
8759
diff
changeset
|
152 local old_hook = active_debug_hook; |
|
c99afee1c548
util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents:
8759
diff
changeset
|
153 active_debug_hook = new_hook; |
|
c99afee1c548
util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents:
8759
diff
changeset
|
154 return old_hook; |
|
c99afee1c548
util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents:
8759
diff
changeset
|
155 end |
|
c99afee1c548
util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents:
8759
diff
changeset
|
156 |
|
1507
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
157 return { |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
158 add_handler = add_handler; |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
159 remove_handler = remove_handler; |
|
3499
91c55ae31ef3
util.events: Fixed the exposed API for adding/removing sets of event handlers.
Waqas Hussain <waqas20@gmail.com>
parents:
3498
diff
changeset
|
160 add_handlers = add_handlers; |
|
91c55ae31ef3
util.events: Fixed the exposed API for adding/removing sets of event handlers.
Waqas Hussain <waqas20@gmail.com>
parents:
3498
diff
changeset
|
161 remove_handlers = remove_handlers; |
|
6664
5466f24e51c9
util.events: Add get_handlers() method
Matthew Wild <mwild1@gmail.com>
parents:
6641
diff
changeset
|
162 get_handlers = get_handlers; |
|
6638
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
163 wrappers = { |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
164 add_handler = add_wrapper; |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
165 remove_handler = remove_wrapper; |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
166 }; |
|
11058
c99afee1c548
util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents:
8759
diff
changeset
|
167 |
|
6638
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
168 add_wrapper = add_wrapper; |
|
9d2b56fd6b47
util.events: Add support for event wrappers, functions which can wrap the calling of event handlers to run code before/after an event (for debugging, statistics, logging purposes, etc.)
Matthew Wild <mwild1@gmail.com>
parents:
5776
diff
changeset
|
169 remove_wrapper = remove_wrapper; |
|
11058
c99afee1c548
util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents:
8759
diff
changeset
|
170 |
|
c99afee1c548
util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents:
8759
diff
changeset
|
171 set_debug_hook = set_debug_hook; |
|
c99afee1c548
util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents:
8759
diff
changeset
|
172 |
|
1507
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
173 fire_event = fire_event; |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
174 _handlers = handlers; |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
175 _event_map = event_map; |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
176 }; |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
177 end |
|
92357dffe743
util.events: Convert from Windows line endings
Matthew Wild <mwild1@gmail.com>
parents:
1417
diff
changeset
|
178 |
|
6777
5de6b93d0190
util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents:
6665
diff
changeset
|
179 return { |
|
5de6b93d0190
util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents:
6665
diff
changeset
|
180 new = new; |
|
5de6b93d0190
util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents:
6665
diff
changeset
|
181 }; |