aboutsummaryrefslogtreecommitdiff
path: root/tests/basic.lua
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2024-05-07 17:56:10 +0200
committerBenoit Germain <benoit.germain@ubisoft.com>2024-05-07 17:56:10 +0200
commit6d271c5796eae14d1dc60e778435495ebfb540d8 (patch)
tree3bccba196595305ffd5f2b30f838dd39fbc5d51d /tests/basic.lua
parent5c7ef34404d3367542275d76b49f276ab035639f (diff)
downloadlanes-6d271c5796eae14d1dc60e778435495ebfb540d8.tar.gz
lanes-6d271c5796eae14d1dc60e778435495ebfb540d8.tar.bz2
lanes-6d271c5796eae14d1dc60e778435495ebfb540d8.zip
Linda API changes
* timeout clarifications (negative values are no longer accepted, use nil instead) * linda(send, linda.null, key, ...) removed, if you want to send a nil, just do it as usual
Diffstat (limited to 'tests/basic.lua')
-rw-r--r--tests/basic.lua296
1 files changed, 151 insertions, 145 deletions
diff --git a/tests/basic.lua b/tests/basic.lua
index 1cf37e6..85a9889 100644
--- a/tests/basic.lua
+++ b/tests/basic.lua
@@ -8,16 +8,16 @@
8-- 8--
9 9
10local require_lanes_result_1, require_lanes_result_2 = require "lanes".configure{ with_timers = false, internal_allocator = "libc"} 10local require_lanes_result_1, require_lanes_result_2 = require "lanes".configure{ with_timers = false, internal_allocator = "libc"}
11print( "require_lanes_result:", require_lanes_result_1, require_lanes_result_2) 11print("require_lanes_result:", require_lanes_result_1, require_lanes_result_2)
12local lanes = require_lanes_result_1 12local lanes = require_lanes_result_1
13 13
14local require_assert_result_1, require_assert_result_2 = require "assert" -- assert.fails() 14local require_assert_result_1, require_assert_result_2 = require "assert" -- assert.fails()
15print( "require_assert_result:", require_assert_result_1, require_assert_result_2) 15print("require_assert_result:", require_assert_result_1, require_assert_result_2)
16 16
17local lanes_gen= assert( lanes.gen ) 17local lanes_gen= assert(lanes.gen)
18local lanes_linda= assert( lanes.linda ) 18local lanes_linda= assert(lanes.linda)
19 19
20local tostring= assert( tostring ) 20local tostring= assert(tostring)
21 21
22local function PRINT(...) 22local function PRINT(...)
23 local str="" 23 local str=""
@@ -29,8 +29,8 @@ local function PRINT(...)
29 end 29 end
30end 30end
31 31
32local gc_cb = function( name_, status_) 32local gc_cb = function(name_, status_)
33 PRINT( " ---> lane '" .. name_ .. "' collected with status " .. status_) 33 PRINT(" ---> lane '" .. name_ .. "' collected with status '" .. status_ .. "'")
34end 34end
35--gc_cb = nil 35--gc_cb = nil
36 36
@@ -41,9 +41,9 @@ local tables_match
41 41
42-- true if 'a' is a subtable of 'b' 42-- true if 'a' is a subtable of 'b'
43-- 43--
44local function subtable( a, b ) 44local function subtable(a, b)
45 -- 45 --
46 assert( type(a)=="table" and type(b)=="table" ) 46 assert(type(a)=="table" and type(b)=="table")
47 47
48 for k,v in pairs(b) do 48 for k,v in pairs(b) do
49 if type(v)~=type(a[k]) then 49 if type(v)~=type(a[k]) then
@@ -59,18 +59,18 @@ end
59 59
60-- true when contents of 'a' and 'b' are identical 60-- true when contents of 'a' and 'b' are identical
61-- 61--
62tables_match= function( a, b ) 62tables_match= function(a, b)
63 return subtable( a, b ) and subtable( b, a ) 63 return subtable(a, b) and subtable(b, a)
64end 64end
65 65
66-- ################################################################################################## 66-- ##################################################################################################
67-- ################################################################################################## 67-- ##################################################################################################
68-- ################################################################################################## 68-- ##################################################################################################
69 69
70PRINT( "\n\n", "---=== Tasking (basic) ===---", "\n\n") 70PRINT("\n\n", "---=== Tasking (basic) ===---", "\n\n")
71 71
72local function task( a, b, c ) 72local function task(a, b, c)
73 set_debug_threadname( "task("..a..","..b..","..c..")") 73 set_debug_threadname("task("..a..","..b..","..c..")")
74 --error "111" -- testing error messages 74 --error "111" -- testing error messages
75 assert(hey) 75 assert(hey)
76 local v=0 76 local v=0
@@ -80,20 +80,20 @@ local function task( a, b, c )
80 return v, hey 80 return v, hey
81end 81end
82 82
83local task_launch= lanes_gen( "", { globals={hey=true}, gc_cb = gc_cb}, task ) 83local task_launch= lanes_gen("", { globals={hey=true}, gc_cb = gc_cb}, task)
84 -- base stdlibs, normal priority 84 -- base stdlibs, normal priority
85 85
86-- 'task_launch' is a factory of multithreaded tasks, we can launch several: 86-- 'task_launch' is a factory of multithreaded tasks, we can launch several:
87 87
88local lane1= task_launch( 100,200,3 ) 88local lane1= task_launch(100,200,3)
89local lane2= task_launch( 200,300,4 ) 89local lane2= task_launch(200,300,4)
90 90
91-- At this stage, states may be "pending", "running" or "done" 91-- At this stage, states may be "pending", "running" or "done"
92 92
93local st1,st2= lane1.status, lane2.status 93local st1,st2= lane1.status, lane2.status
94PRINT(st1,st2) 94PRINT(st1,st2)
95assert( st1=="pending" or st1=="running" or st1=="done" ) 95assert(st1=="pending" or st1=="running" or st1=="done")
96assert( st2=="pending" or st2=="running" or st2=="done" ) 96assert(st2=="pending" or st2=="running" or st2=="done")
97 97
98-- Accessing results ([1..N]) pends until they are available 98-- Accessing results ([1..N]) pends until they are available
99-- 99--
@@ -101,14 +101,14 @@ PRINT("waiting...")
101local v1, v1_hey= lane1[1], lane1[2] 101local v1, v1_hey= lane1[1], lane1[2]
102local v2, v2_hey= lane2[1], lane2[2] 102local v2, v2_hey= lane2[1], lane2[2]
103 103
104PRINT( v1, v1_hey ) 104PRINT(v1, v1_hey)
105assert( v1_hey == true ) 105assert(v1_hey == true)
106 106
107PRINT( v2, v2_hey ) 107PRINT(v2, v2_hey)
108assert( v2_hey == true ) 108assert(v2_hey == true)
109 109
110assert( lane1.status == "done" ) 110assert(lane1.status == "done")
111assert( lane1.status == "done" ) 111assert(lane1.status == "done")
112lane1, lane2 = nil 112lane1, lane2 = nil
113collectgarbage() 113collectgarbage()
114 114
@@ -116,9 +116,9 @@ collectgarbage()
116-- ################################################################################################## 116-- ##################################################################################################
117-- ################################################################################################## 117-- ##################################################################################################
118 118
119PRINT( "\n\n", "---=== Tasking (cancelling) ===---", "\n\n") 119PRINT("\n\n", "---=== Tasking (cancelling) ===---", "\n\n")
120 120
121local task_launch2= lanes_gen( "", { globals={hey=true}, gc_cb = gc_cb}, task ) 121local task_launch2= lanes_gen("", { globals={hey=true}, gc_cb = gc_cb}, task)
122 122
123local N=999999999 123local N=999999999
124local lane9= task_launch2(1,N,1) -- huuuuuuge... 124local lane9= task_launch2(1,N,1) -- huuuuuuge...
@@ -129,7 +129,7 @@ local st
129local t0= os.time() 129local t0= os.time()
130while os.time()-t0 < 5 do 130while os.time()-t0 < 5 do
131 st= lane9.status 131 st= lane9.status
132 io.stderr:write( (i==1) and st.." " or '.' ) 132 io.stderr:write((i==1) and st.." " or '.')
133 if st~="pending" then break end 133 if st~="pending" then break end
134end 134end
135PRINT(" "..st) 135PRINT(" "..st)
@@ -138,36 +138,36 @@ if st=="error" then
138 local _= lane9[0] -- propagate the error here 138 local _= lane9[0] -- propagate the error here
139end 139end
140if st=="done" then 140if st=="done" then
141 error( "Looping to "..N.." was not long enough (cannot test cancellation)" ) 141 error("Looping to "..N.." was not long enough (cannot test cancellation)")
142end 142end
143assert( st=="running" ) 143assert(st=="running")
144 144
145lane9:cancel( "count", 100) -- 0 timeout, 100 instructions count hook 145lane9:cancel("count", 100) -- 0 timeout, 100 instructions count hook
146 146
147local t0= os.time() 147local t0= os.time()
148while os.time()-t0 < 5 do 148while os.time()-t0 < 5 do
149 st= lane9.status 149 st= lane9.status
150 io.stderr:write( (i==1) and st.." " or '.' ) 150 io.stderr:write((i==1) and st.." " or '.')
151 if st~="running" then break end 151 if st~="running" then break end
152end 152end
153PRINT(" "..st) 153PRINT(" "..st)
154assert( st == "cancelled" ) 154assert(st == "cancelled")
155 155
156-- cancellation of lanes waiting on a linda 156-- cancellation of lanes waiting on a linda
157local limited = lanes.linda("limited") 157local limited = lanes.linda("limited")
158limited:limit( "key", 1) 158limited:limit("key", 1)
159-- [[################################################ 159-- [[################################################
160limited:send( "key", "hello") -- saturate linda 160limited:send("key", "hello") -- saturate linda
161for k, v in pairs( limited:dump()) do 161for k, v in pairs(limited:dump()) do
162 PRINT("limited[" .. tostring( k) .. "] = " .. tostring( v)) 162 PRINT("limited[" .. tostring(k) .. "] = " .. tostring(v))
163end 163end
164local wait_send = function() 164local wait_send = function()
165 local a,b 165 local a,b
166 set_finalizer( function() print( "wait_send", a, b) end) 166 set_finalizer(function() print("wait_send", a, b) end)
167 a,b = limited:send( "key", "bybye") -- infinite timeout, returns only when lane is cancelled 167 a,b = limited:send("key", "bybye") -- infinite timeout, returns only when lane is cancelled
168end 168end
169 169
170local wait_send_lane = lanes.gen( "*", wait_send)() 170local wait_send_lane = lanes.gen("*", wait_send)()
171repeat until wait_send_lane.status == "waiting" 171repeat until wait_send_lane.status == "waiting"
172print "wait_send_lane is waiting" 172print "wait_send_lane is waiting"
173wait_send_lane:cancel() -- hard cancel, 0 timeout 173wait_send_lane:cancel() -- hard cancel, 0 timeout
@@ -176,11 +176,11 @@ print "wait_send_lane is cancelled"
176--################################################]] 176--################################################]]
177local wait_receive = function() 177local wait_receive = function()
178 local k, v 178 local k, v
179 set_finalizer( function() print( "wait_receive", k, v) end) 179 set_finalizer(function() print("wait_receive", k, v) end)
180 k, v = limited:receive( "dummy") -- infinite timeout, returns only when lane is cancelled 180 k, v = limited:receive("dummy") -- infinite timeout, returns only when lane is cancelled
181end 181end
182 182
183local wait_receive_lane = lanes.gen( "*", wait_receive)() 183local wait_receive_lane = lanes.gen("*", wait_receive)()
184repeat until wait_receive_lane.status == "waiting" 184repeat until wait_receive_lane.status == "waiting"
185print "wait_receive_lane is waiting" 185print "wait_receive_lane is waiting"
186wait_receive_lane:cancel() -- hard cancel, 0 timeout 186wait_receive_lane:cancel() -- hard cancel, 0 timeout
@@ -189,11 +189,11 @@ print "wait_receive_lane is cancelled"
189--################################################]] 189--################################################]]
190local wait_receive_batched = function() 190local wait_receive_batched = function()
191 local k, v1, v2 191 local k, v1, v2
192 set_finalizer( function() print( "wait_receive_batched", k, v1, v2) end) 192 set_finalizer(function() print("wait_receive_batched", k, v1, v2) end)
193 k, v1, v2 = limited:receive( limited.batched, "dummy", 2) -- infinite timeout, returns only when lane is cancelled 193 k, v1, v2 = limited:receive(limited.batched, "dummy", 2) -- infinite timeout, returns only when lane is cancelled
194end 194end
195 195
196local wait_receive_batched_lane = lanes.gen( "*", wait_receive_batched)() 196local wait_receive_batched_lane = lanes.gen("*", wait_receive_batched)()
197repeat until wait_receive_batched_lane.status == "waiting" 197repeat until wait_receive_batched_lane.status == "waiting"
198print "wait_receive_batched_lane is waiting" 198print "wait_receive_batched_lane is waiting"
199wait_receive_batched_lane:cancel() -- hard cancel, 0 timeout 199wait_receive_batched_lane:cancel() -- hard cancel, 0 timeout
@@ -205,120 +205,126 @@ print "wait_receive_batched_lane is cancelled"
205-- ################################################################################################## 205-- ##################################################################################################
206-- ################################################################################################## 206-- ##################################################################################################
207 207
208PRINT( "\n\n", "---=== Communications ===---", "\n\n") 208PRINT("\n\n", "---=== Communications ===---", "\n\n")
209 209
210local function WR(...) io.stderr:write(...) end 210local function WR(...) io.stderr:write(...) end
211 211
212local chunk= function( linda ) 212local chunk= function(linda)
213 set_debug_threadname "chunk" 213 local function receive() return linda:receive("->") end
214 local function receive() return linda:receive( "->" ) end 214 local function send(...) linda:send("<-", ...) end
215 local function send(...) linda:send( "<-", ... ) end
216 215
217 WR( "Lane starts!\n" ) 216 WR("Lane starts!\n")
218 217
219 local k,v 218 local k,v
220 k,v=receive(); WR( v.." received\n" ); assert( v==1 ) 219 k,v=receive(); WR(v.." received\n"); assert(v==1)
221 k,v=receive(); WR( v.." received\n" ); assert( v==2 ) 220 k,v=receive(); WR(v.." received\n"); assert(v==2)
222 k,v=receive(); WR( v.." received\n" ); assert( v==3 ) 221 k,v=receive(); WR(v.." received\n"); assert(v==3)
222 k,v=receive(); WR(tostring(v).." received\n"); assert(v==nil)
223 223
224 send( 1,2,3 ); WR( "1,2,3 sent\n" ) 224 send(1,2,3); WR("1,2,3 sent\n")
225 send 'a'; WR( "'a' sent\n" ) 225 send 'a'; WR("'a' sent\n")
226 send { 'a', 'b', 'c', d=10 }; WR( "{'a','b','c',d=10} sent\n" ) 226 send(nil); WR("nil sent\n")
227 send { 'a', 'b', 'c', d=10 }; WR("{'a','b','c',d=10} sent\n")
227 228
228 k,v=receive(); WR( v.." received\n" ); assert( v==4 ) 229 k,v=receive(); WR(v.." received\n"); assert(v==4)
229 230
230 local subT1 = { "subT1"} 231 local subT1 = { "subT1"}
231 local subT2 = { "subT2"} 232 local subT2 = { "subT2"}
232 send { subT1, subT2, subT1, subT2}; WR( "{ subT1, subT2, subT1, subT2} sent\n" ) 233 send { subT1, subT2, subT1, subT2}; WR("{ subT1, subT2, subT1, subT2} sent\n")
233 234
234 WR( "Lane ends!\n" ) 235 WR("Lane ends!\n")
235end 236end
236 237
237local linda= lanes_linda("communications") 238local linda = lanes_linda("communications")
238assert( type(linda) == "userdata" ) 239assert(type(linda) == "userdata" and tostring(linda) == "Linda: communications")
239 -- 240 --
240 -- ["->"] master -> slave 241 -- ["->"] master -> slave
241 -- ["<-"] slave <- master 242 -- ["<-"] slave <- master
242 243
243local function PEEK() return linda:get("<-") end 244local function PEEK() return linda:get("<-") end
244local function SEND(...) linda:send( "->", ... ) end 245local function SEND(...) linda:send("->", ...) end
245local function RECEIVE() local k,v = linda:receive( 1, "<-" ) return v end 246local function RECEIVE() local k,v = linda:receive(1, "<-") return v end
246 247
247local t= lanes_gen("io", {gc_cb = gc_cb}, chunk)(linda) -- prepare & launch 248local comms_lane = lanes_gen("io", {gc_cb = gc_cb, name = "auto"}, chunk)(linda) -- prepare & launch
248 249
249SEND(1); WR( "1 sent\n" ) 250SEND(1); WR("1 sent\n")
250SEND(2); WR( "2 sent\n" ) 251SEND(2); WR("2 sent\n")
252SEND(3); WR("3 sent\n")
251for i=1,100 do 253for i=1,100 do
252 WR "." 254 WR "."
253 assert( PEEK() == nil ) -- nothing coming in, yet 255 lanes.sleep(0.0001)
256 assert(PEEK() == nil) -- nothing coming in, yet
254end 257end
255SEND(3); WR( "3 sent\n" ) 258SEND(nil); WR("\nnil sent\n")
256 259
257local a,b,c= RECEIVE(), RECEIVE(), RECEIVE() 260local a,b,c = RECEIVE(), RECEIVE(), RECEIVE()
258 261
259print( "lane status: " .. t.status) 262print("lane status: " .. comms_lane.status)
260if t.status == "error" then 263if comms_lane.status == "error" then
261 print( t:join()) 264 print(comms_lane:join())
262else 265else
263 WR( a..", "..b..", "..c.." received\n" ) 266 WR(a..", "..b..", "..c.." received\n")
264end 267end
265 268
266assert( a==1 and b==2 and c==3 ) 269assert(a==1 and b==2 and c==3)
267 270
268local a= RECEIVE(); WR( a.." received\n" ) 271local a = RECEIVE(); WR(a.." received\n")
269assert( a=='a' ) 272assert(a=='a')
270 273
271local a= RECEIVE(); WR( type(a).." received\n" ) 274local null = RECEIVE(); WR(tostring(null).." received\n")
272assert( tables_match( a, {'a','b','c',d=10} ) ) 275assert(null==nil)
273 276
274assert( PEEK() == nil ) 277local out_t = RECEIVE(); WR(type(out_t).." received\n")
278assert(tables_match(out_t, {'a','b','c',d=10}))
279
280assert(PEEK() == nil)
275SEND(4) 281SEND(4)
276 282
277local complex_table = RECEIVE(); WR( type(complex_table).." received\n" ) 283local complex_table = RECEIVE(); WR(type(complex_table).." received\n")
278assert( complex_table[1] == complex_table[3] and complex_table[2] == complex_table[4]) 284assert(complex_table[1] == complex_table[3] and complex_table[2] == complex_table[4])
279WR( table.concat( {complex_table[1][1],complex_table[2][1],complex_table[3][1],complex_table[4][1]},", ")) 285WR(table.concat({complex_table[1][1],complex_table[2][1],complex_table[3][1],complex_table[4][1]},", "))
280 286
281WR("collectgarbage") 287WR("collectgarbage")
282t = nil 288comms_lane = nil
283collectgarbage() 289collectgarbage()
284-- wait 290-- wait
285WR("waiting 1s") 291WR("waiting 1s")
286linda:receive( 1, "wait") 292lanes.sleep(1)
287 293
288-- ################################################################################################## 294-- ##################################################################################################
289-- ################################################################################################## 295-- ##################################################################################################
290-- ################################################################################################## 296-- ##################################################################################################
291 297
292PRINT( "\n\n", "---=== Stdlib naming ===---", "\n\n") 298PRINT("\n\n", "---=== Stdlib naming ===---", "\n\n")
293 299
294local function dump_g( _x) 300local function dump_g(_x)
295 set_debug_threadname "dump_g" 301 set_debug_threadname "dump_g"
296 assert(print) 302 assert(print)
297 print( "### dumping _G for '" .. _x .. "'") 303 print("### dumping _G for '" .. _x .. "'")
298 for k, v in pairs( _G) do 304 for k, v in pairs(_G) do
299 print( "\t" .. k .. ": " .. type( v)) 305 print("\t" .. k .. ": " .. type(v))
300 end 306 end
301 return true 307 return true
302end 308end
303 309
304local function io_os_f( _x) 310local function io_os_f(_x)
305 set_debug_threadname "io_os_f" 311 set_debug_threadname "io_os_f"
306 assert(print) 312 assert(print)
307 print( "### checking io and os libs existence for '" .. _x .. "'") 313 print("### checking io and os libs existence for '" .. _x .. "'")
308 assert(io) 314 assert(io)
309 assert(os) 315 assert(os)
310 return true 316 return true
311end 317end
312 318
313local function coro_f( _x) 319local function coro_f(_x)
314 set_debug_threadname "coro_f" 320 set_debug_threadname "coro_f"
315 assert(print) 321 assert(print)
316 print( "### checking coroutine lib existence for '" .. _x .. "'") 322 print("### checking coroutine lib existence for '" .. _x .. "'")
317 assert(coroutine) 323 assert(coroutine)
318 return true 324 return true
319end 325end
320 326
321assert.fails( function() lanes_gen( "xxx", {gc_cb = gc_cb}, io_os_f ) end ) 327assert.fails(function() lanes_gen("xxx", {gc_cb = gc_cb}, io_os_f) end)
322 328
323local stdlib_naming_tests = 329local stdlib_naming_tests =
324{ 330{
@@ -333,9 +339,9 @@ local stdlib_naming_tests =
333 { "io,os,base", io_os_f}, 339 { "io,os,base", io_os_f},
334} 340}
335 341
336for _, t in ipairs( stdlib_naming_tests) do 342for _, t in ipairs(stdlib_naming_tests) do
337 local f= lanes_gen( t[1], {gc_cb = gc_cb}, t[2]) -- any delimiter will do 343 local f= lanes_gen(t[1], {gc_cb = gc_cb}, t[2]) -- any delimiter will do
338 assert( f(t[1])[1] ) 344 assert(f(t[1])[1])
339end 345end
340 346
341WR("collectgarbage") 347WR("collectgarbage")
@@ -345,17 +351,17 @@ collectgarbage()
345-- ################################################################################################## 351-- ##################################################################################################
346-- ################################################################################################## 352-- ##################################################################################################
347 353
348PRINT( "\n\n", "---=== Comms criss cross ===---", "\n\n") 354PRINT("\n\n", "---=== Comms criss cross ===---", "\n\n")
349 355
350-- We make two identical lanes, which are using the same Linda channel. 356-- We make two identical lanes, which are using the same Linda channel.
351-- 357--
352local tc= lanes_gen( "io", {gc_cb = gc_cb}, 358local tc= lanes_gen("io", {gc_cb = gc_cb},
353 function( linda, ch_in, ch_out ) 359 function(linda, ch_in, ch_out)
354 set_debug_threadname( "criss cross " .. ch_in .. " -> " .. ch_out) 360 set_debug_threadname("criss cross " .. ch_in .. " -> " .. ch_out)
355 local function STAGE(str) 361 local function STAGE(str)
356 io.stderr:write( ch_in..": "..str.."\n" ) 362 io.stderr:write(ch_in..": "..str.."\n")
357 linda:send( nil, ch_out, str ) 363 linda:send(nil, ch_out, str)
358 local k,v= linda:receive( nil, ch_in ) 364 local k,v= linda:receive(nil, ch_in)
359 assert(v==str) 365 assert(v==str)
360 end 366 end
361 STAGE("Hello") 367 STAGE("Hello")
@@ -378,103 +384,103 @@ collectgarbage()
378-- ################################################################################################## 384-- ##################################################################################################
379-- ################################################################################################## 385-- ##################################################################################################
380 386
381PRINT( "\n\n", "---=== Receive & send of code ===---", "\n\n") 387PRINT("\n\n", "---=== Receive & send of code ===---", "\n\n")
382 388
383local upvalue="123" 389local upvalue="123"
384 390
385local function chunk2( linda ) 391local function chunk2(linda)
386 assert( upvalue=="123" ) -- even when running as separate thread 392 assert(upvalue=="123") -- even when running as separate thread
387 -- function name & line number should be there even as separate thread 393 -- function name & line number should be there even as separate thread
388 -- 394 --
389 local info= debug.getinfo(1) -- 1 = us 395 local info= debug.getinfo(1) -- 1 = us
390 -- 396 --
391 for k,v in pairs(info) do PRINT(k,v) end 397 for k,v in pairs(info) do PRINT(k,v) end
392 398
393 assert( info.nups == (_VERSION == "Lua 5.1" and 2 or 3) ) -- one upvalue + PRINT + _ENV (Lua 5.2 only) 399 assert(info.nups == (_VERSION == "Lua 5.1" and 2 or 3)) -- one upvalue + PRINT + _ENV (Lua 5.2 only)
394 assert( info.what == "Lua" ) 400 assert(info.what == "Lua")
395 --assert( info.name == "chunk2" ) -- name does not seem to come through 401 --assert(info.name == "chunk2") -- name does not seem to come through
396 assert( string.match( info.source, "^@.*basic.lua$" ) ) 402 assert(string.match(info.source, "^@.*basic.lua$"))
397 assert( string.match( info.short_src, "^.*basic.lua$" ) ) 403 assert(string.match(info.short_src, "^.*basic.lua$"))
398 -- These vary so let's not be picky (they're there..) 404 -- These vary so let's not be picky (they're there..)
399 -- 405 --
400 assert( info.linedefined > 200 ) -- start of 'chunk2' 406 assert(info.linedefined > 200) -- start of 'chunk2'
401 assert( info.currentline > info.linedefined ) -- line of 'debug.getinfo' 407 assert(info.currentline > info.linedefined) -- line of 'debug.getinfo'
402 assert( info.lastlinedefined > info.currentline ) -- end of 'chunk2' 408 assert(info.lastlinedefined > info.currentline) -- end of 'chunk2'
403 local k,func= linda:receive( "down" ) 409 local k,func= linda:receive("down")
404 assert( type(func)=="function" ) 410 assert(type(func)=="function")
405 assert( k=="down" ) 411 assert(k=="down")
406 412
407 func(linda) 413 func(linda)
408 414
409 local k,str= linda:receive( "down" ) 415 local k,str= linda:receive("down")
410 assert( str=="ok" ) 416 assert(str=="ok")
411 417
412 linda:send( "up", function() return ":)" end, "ok2" ) 418 linda:send("up", function() return ":)" end, "ok2")
413end 419end
414 420
415local linda= lanes.linda("linda") 421local linda= lanes.linda("linda")
416local t2= lanes_gen( "debug,string,io", {gc_cb = gc_cb}, chunk2 )(linda) -- prepare & launch 422local t2= lanes_gen("debug,string,io", {gc_cb = gc_cb}, chunk2)(linda) -- prepare & launch
417linda:send( "down", function(linda) linda:send( "up", "ready!" ) end, 423linda:send("down", function(linda) linda:send("up", "ready!") end,
418 "ok" ) 424 "ok")
419-- wait to see if the tiny function gets executed 425-- wait to see if the tiny function gets executed
420-- 426--
421local k,s= linda:receive( 1, "up" ) 427local k,s= linda:receive(1, "up")
422if t2.status == "error" then 428if t2.status == "error" then
423 print( "t2 error: " , t2:join()) 429 print("t2 error: " , t2:join())
424end 430end
425PRINT(s) 431PRINT(s)
426assert( s=="ready!" ) 432assert(s=="ready!")
427 433
428-- returns of the 'chunk2' itself 434-- returns of the 'chunk2' itself
429-- 435--
430local k,f= linda:receive( "up" ) 436local k,f= linda:receive("up")
431assert( type(f)=="function" ) 437assert(type(f)=="function")
432 438
433local s2= f() 439local s2= f()
434assert( s2==":)" ) 440assert(s2==":)")
435 441
436local k,ok2= linda:receive( "up" ) 442local k,ok2= linda:receive("up")
437assert( ok2 == "ok2" ) 443assert(ok2 == "ok2")
438 444
439-- ################################################################################################## 445-- ##################################################################################################
440-- ################################################################################################## 446-- ##################################################################################################
441-- ################################################################################################## 447-- ##################################################################################################
442 448
443PRINT( "\n\n", "---=== :join test ===---", "\n\n") 449PRINT("\n\n", "---=== :join test ===---", "\n\n")
444 450
445-- NOTE: 'unpack()' cannot be used on the lane handle; it will always return nil 451-- NOTE: 'unpack()' cannot be used on the lane handle; it will always return nil
446-- (unless [1..n] has been read earlier, in which case it would seemingly 452-- (unless [1..n] has been read earlier, in which case it would seemingly
447-- work). 453-- work).
448 454
449local S= lanes_gen( "table", {gc_cb = gc_cb}, 455local S= lanes_gen("table", {gc_cb = gc_cb},
450 function(arg) 456 function(arg)
451 set_debug_threadname "join test lane" 457 set_debug_threadname "join test lane"
452 set_finalizer( function() end) 458 set_finalizer(function() end)
453 aux= {} 459 aux= {}
454 for i, v in ipairs(arg) do 460 for i, v in ipairs(arg) do
455 table.insert (aux, 1, v) 461 table.insert (aux, 1, v)
456 end 462 end
457 -- unpack was renamed table.unpack in Lua 5.2: cater for both! 463 -- unpack was renamed table.unpack in Lua 5.2: cater for both!
458 return (unpack or table.unpack)(aux) 464 return (unpack or table.unpack)(aux)
459end ) 465end)
460 466
461h= S { 12, 13, 14 } -- execution starts, h[1..3] will get the return values 467h= S { 12, 13, 14 } -- execution starts, h[1..3] will get the return values
462-- wait a bit so that the lane hasa chance to set its debug name 468-- wait a bit so that the lane has a chance to set its debug name
463linda:receive(0.5, "gloupti") 469lanes.sleep(0.5)
464print( "joining with '" .. h:get_debug_threadname() .. "'") 470print("joining with '" .. h:get_debug_threadname() .. "'")
465local a,b,c,d= h:join() 471local a,b,c,d= h:join()
466if h.status == "error" then 472if h.status == "error" then
467 print( h:get_debug_threadname(), "error: " , a, b, c, d) 473 print(h:get_debug_threadname(), "error: " , a, b, c, d)
468else 474else
469 print( h:get_debug_threadname(), a,b,c,d) 475 print(h:get_debug_threadname(), a,b,c,d)
470 assert(a==14) 476 assert(a==14)
471 assert(b==13) 477 assert(b==13)
472 assert(c==12) 478 assert(c==12)
473 assert(d==nil) 479 assert(d==nil)
474end 480end
475 481
476local nameof_type, nameof_name = lanes.nameof( print) 482local nameof_type, nameof_name = lanes.nameof(print)
477PRINT( "name of " .. nameof_type .. " print = '" .. nameof_name .. "'") 483PRINT("name of " .. nameof_type .. " print = '" .. nameof_name .. "'")
478 484
479-- 485--
480io.stderr:write "Done! :)\n" 486io.stderr:write "Done! :)\n"