Skip to content

Commit ced5c0c

Browse files
committed
rcu-based msgbox
1 parent 348cfe5 commit ced5c0c

File tree

1 file changed

+70
-2
lines changed

1 file changed

+70
-2
lines changed

lib/mailbox.lua

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
--
22
-- SPDX-FileCopyrightText: (c) 2024 Ring Zero Desenvolvimento de Software LTDA
3-
-- SPDX-License-Identifier: MIT OR GPL-2.0-only
3+
-- SPDX-License-Identifier: MIT OR GPL-2.0-only
44
--
55

66
local fifo = require("fifo")
77
local completion = require("completion")
88

9+
local lunatik = require("lunatik")
10+
local rcu_table = require("rcu").table
11+
local new_data = require("data").new
12+
913
-- Mailbox using fifo and completion
1014

11-
local mailbox = {}
15+
local mailbox = {}
1216
local MailBox = {}
1317
MailBox.__index = MailBox
1418

@@ -61,5 +65,69 @@ function MailBox:send(message)
6165
if self.event then self.event:complete() end
6266
end
6367

68+
-- Msgbox using rcu
69+
70+
local env = lunatik._ENV
71+
72+
local MsgBox = {}
73+
MsgBox.__index = MsgBox
74+
75+
local function new_rcu(name, hsize, allowed, forbidden)
76+
hsize = hsize or 1024
77+
78+
local mbox = env[name]
79+
if not mbox then
80+
mbox = rcu_table(hsize)
81+
mbox.last_write = new_data(8)
82+
mbox.last_read = new_data(8)
83+
env[name] = mbox
84+
end
85+
local self = {
86+
name = name,
87+
[forbidden] = function () error(allowed .. "-only mailbox") end
88+
}
89+
return setmetatable(self, MsgBox)
90+
end
91+
92+
function MsgBox:send(msg)
93+
-- We don’t set mbox within the object, to avoid duplicates in race conditions
94+
local mbox = env[self.name]
95+
local last_write = mbox.last_write
96+
local index = 1 + last_write:getnumber(0)
97+
98+
local msg_data = new_data(#msg)
99+
msg_data:setstring(0, msg)
100+
mbox[index] = msg_data
101+
102+
last_write:setnumber(0, index)
103+
end
104+
105+
function MsgBox:receive()
106+
local mbox = env[self.name]
107+
local last_read = mbox.last_read
108+
local last_write = mbox.last_write
109+
local index = last_read:getnumber(0)
110+
111+
if index ~= last_write:getnumber(0) then
112+
index = index + 1
113+
local msg_data = mbox[index]
114+
115+
if msg_data then -- This should be, but this condition avoids race conditions
116+
last_read:setnumber(0, index)
117+
local msg = msg_data:getstring(0)
118+
mbox[index] = nil
119+
return msg
120+
end
121+
end
122+
end
123+
124+
function mailbox.rcu_inbox(name, hsize)
125+
return new_rcu(name, hsize, 'receive', 'send')
126+
end
127+
128+
function mailbox.rcu_outbox(name, hsize)
129+
return new_rcu(name, hsize, 'send', 'receive')
130+
end
131+
64132
return mailbox
65133

0 commit comments

Comments
 (0)