Skip to content

Commit 6edc619

Browse files
gitmsrcmsj
authored andcommitted
Avoid reentrance when in printReplacement
hs.ipc replaces the print function with one that calls the original, but also sends anything that print prints to any of the remote connections. If you have debugging enabled, that means that the moment the remote connection is created, a bunch of print statements are sent to the this connection. The problem I had is that my use of hs (command) was simply to send a message to the screen: warning () { hs -c "hs.alert.show('$1')" > /dev/null echo "$1" } The connection was so ephemeral, than I frequently got errors (related to the client no long existing) which were tried to be send to the client... so I ended with the following messages: 2023-12-31 22:00:02: 22:00:02 ERROR: LuaSkin: hs.ipc callback is being called recursively. Check your callback function, it is triggering further IPC messages. This message was triggered after reaching 5 recursive callbacks. This code avoid recursion for the same IPC client by keeping a counter of how many times the client has entered the critical region.
1 parent 251f5af commit 6edc619

File tree

1 file changed

+35
-2
lines changed

1 file changed

+35
-2
lines changed

extensions/ipc/ipc.lua

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,52 @@ local MSG_ID = {
3333
CONSOLE = 3, -- cloned console output
3434
}
3535

36+
-- avoid printReplacement to be reentrant
37+
-- otherwise errors might cascade into lots of recursive prints
38+
module.insidePrintInstances = {}
39+
40+
module.print_enter = function(instance)
41+
val = module.insidePrintInstances[instance] or 0
42+
module.insidePrintInstances[instance] = val + 1
43+
end
44+
45+
module.print_exit = function(instance)
46+
-- make sure instance exists
47+
if module.insidePrintInstances[instance] then
48+
module.insidePrintInstances[instance] = module.insidePrintInstances[instance] - 1
49+
if module.insidePrintInstances[instance] == 0 then
50+
module.insidePrintInstances[instance] = nil
51+
end
52+
end
53+
end
54+
55+
module.print_inside = function(instance)
56+
val = module.insidePrintInstances[instance]
57+
return val and val > 0
58+
end
59+
3660
local originalPrint = print
3761
local printReplacement = function(...)
3862
originalPrint(...)
39-
for _,v in pairs(module.__registeredCLIInstances) do
63+
for i,v in pairs(module.__registeredCLIInstances) do
64+
originalPrint(string.format("to print instance [%s]", i))
4065
if v._cli.console and v.print and not v._cli.quietMode then
4166
-- v.print(...)
4267
-- make it more obvious what is console output versus the command line's
68+
69+
if module.print_inside(i) then
70+
originalPrint(string.format("Instance of [%s] already recursing [%d] times, do not do ",
71+
i, module.insidePrintInstances[i]))
72+
else
73+
module.print_enter(i)
4374
local things = table.pack(...)
4475
local stdout = (things.n > 0) and tostring(things[1]) or ""
4576
for i = 2, things.n do
46-
stdout = stdout .. "\t" .. tostring(things[i])
77+
stdout = stdout .. "\t" .. tostring(things[i])
4778
end
4879
v._cli.remote:sendMessage(stdout .. "\n", MSG_ID.CONSOLE)
80+
module.print_exit(i)
81+
end
4982
end
5083
end
5184
end

0 commit comments

Comments
 (0)