1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
|
--
-- KEEPER.LUA
--
-- Test program for Lua Lanes
--
-- TODO: there is a random crash when nb_user_keepers > 1. Will have to investigate if it rears its ugly head again
-- 3 keepers in addition to the one reserved for the timer linda
local require_lanes_result_1, require_lanes_result_2 = require "lanes".configure{nb_user_keepers = 3, keepers_gc_threshold = 500}
print("require_lanes_result:", require_lanes_result_1, require_lanes_result_2)
local lanes = require_lanes_result_1
local require_assert_result_1, require_assert_result_2 = require "assert" -- assert.fails()
print("require_assert_result:", require_assert_result_1, require_assert_result_2)
-- #################################################################################################
local print_id = 0
local P = function(whence_, ...)
print_id = print_id + 1
print(whence_, print_id .. ".", ...)
end
local PRINT = function(...) P("main", ...) end
local DONE = function()
PRINT "collecting garbage"
collectgarbage()
PRINT "SUCCESS\n"
end
-- #################################################################################################
-- #################################################################################################
if true then
PRINT "========================================================================================="
PRINT "Linda groups test:"
local createLinda = function(...)
return lanes.linda(...)
end
-- should succeed
assert.failsnot(function() createLinda("zero", 0) end)
assert.failsnot(function() createLinda("one", 1) end)
assert.failsnot(function() createLinda("two", 2) end)
assert.failsnot(function() createLinda("three", 3) end)
-- should fail (and not create the lindas)
assert.fails(function() createLinda("minus 1", -1) end)
assert.fails(function() createLinda("none") end)
assert.fails(function() createLinda("four", 4) end)
end
-- should only collect the 4 successfully created lindas
DONE()
-- #################################################################################################
if true then
PRINT "========================================================================================="
PRINT "Linda names test:"
local unnamedLinda1 = lanes.linda(1)
local unnamedLinda2 = lanes.linda("", 2)
local veeeerrrryyyylooongNamedLinda3 = lanes.linda( "veeeerrrryyyylooongNamedLinda", 3)
assert(tostring(veeeerrrryyyylooongNamedLinda3) == "Linda: veeeerrrryyyylooongNamedLinda")
local shortNamedLinda0 = lanes.linda( "short", 0)
assert(tostring(shortNamedLinda0) == "Linda: short")
PRINT(shortNamedLinda0, unnamedLinda1, unnamedLinda2, veeeerrrryyyylooongNamedLinda3)
end
-- collect the 4 lindas we created
DONE()
-- #################################################################################################
if true then
PRINT "========================================================================================="
PRINT "Linda GC test:"
local a = lanes.linda("A", 1)
local b = lanes.linda("B", 2)
local c = lanes.linda("C", 3)
-- store lindas in each other and in themselves
a:set("here", lanes.linda("temporary linda", 0))
b:set("here", a, b, c)
c:set("here", a, b, c)
-- repeatedly add and remove stuff in the linda 'a' so that a GC happens during the keeper operation
for i = 1, 100 do
io.stdout:write "."
for j = 1, 1000 do -- send 1000 tables
-- PRINT("send #" .. j)
a:send("here", {"a", "table", "with", "some", "stuff"}, j)
end
-- PRINT(clearing)
a:set("here") -- clear everything, including the temporary linda for which we have no reference
end
io.stdout:write "\n"
b:set("here")
c:set("here")
end
-- should successfully collect a, b, and c and destroy the underlying Deep objects
DONE()
-- #################################################################################################
if true then
PRINT "========================================================================================="
PRINT "General test:"
local function keeper(linda)
local mt= {
__index= function(_, key)
local _count, _val = linda:get(key)
return _val
end,
__newindex= function( _, key, val )
linda:set( key, val )
end
}
return setmetatable( {}, mt )
end
--
local lindaA= lanes.linda( "A", 1)
local A= keeper( lindaA )
local lindaB= lanes.linda( "B", 2)
local B= keeper( lindaB )
local lindaC= lanes.linda( "C", 3)
local C= keeper( lindaC )
PRINT("Created", lindaA, lindaB, lindaC)
A.some= 1
PRINT("A.some == " .. A.some )
assert( A.some==1 )
B.some= "hoo"
PRINT("B.some == " .. B.some )
assert( B.some=="hoo" )
assert( A.some==1 )
assert( C.some==nil )
function lane()
local PRINT = function(...) P("lane", ...) end
local a= keeper(lindaA)
PRINT("a.some == " .. a.some )
assert( a.some==1 )
a.some= 2
assert( a.some==2 )
PRINT("a.some == " .. a.some )
local c = keeper(lindaC)
assert( c.some==nil )
PRINT("c.some == " .. tostring(c.some))
c.some= 3
assert( c.some==3 )
PRINT("c.some == " .. c.some)
return true
end
PRINT("lane started")
local h= lanes.gen( "io", { name = 'auto' }, lane )()
PRINT("lane joined:", h:join())
PRINT("A.some = " .. A.some )
assert( A.some==2 )
PRINT("C.some = " .. C.some )
assert( C.some==3 )
lindaC:set("some")
assert( C.some==nil )
end
DONE()
print "\nTEST OK"
|