diff options
Diffstat (limited to 'tests/basic.lua')
| -rw-r--r-- | tests/basic.lua | 296 |
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 | ||
| 10 | local require_lanes_result_1, require_lanes_result_2 = require "lanes".configure{ with_timers = false, internal_allocator = "libc"} | 10 | local require_lanes_result_1, require_lanes_result_2 = require "lanes".configure{ with_timers = false, internal_allocator = "libc"} |
| 11 | print( "require_lanes_result:", require_lanes_result_1, require_lanes_result_2) | 11 | print("require_lanes_result:", require_lanes_result_1, require_lanes_result_2) |
| 12 | local lanes = require_lanes_result_1 | 12 | local lanes = require_lanes_result_1 |
| 13 | 13 | ||
| 14 | local require_assert_result_1, require_assert_result_2 = require "assert" -- assert.fails() | 14 | local require_assert_result_1, require_assert_result_2 = require "assert" -- assert.fails() |
| 15 | print( "require_assert_result:", require_assert_result_1, require_assert_result_2) | 15 | print("require_assert_result:", require_assert_result_1, require_assert_result_2) |
| 16 | 16 | ||
| 17 | local lanes_gen= assert( lanes.gen ) | 17 | local lanes_gen= assert(lanes.gen) |
| 18 | local lanes_linda= assert( lanes.linda ) | 18 | local lanes_linda= assert(lanes.linda) |
| 19 | 19 | ||
| 20 | local tostring= assert( tostring ) | 20 | local tostring= assert(tostring) |
| 21 | 21 | ||
| 22 | local function PRINT(...) | 22 | local function PRINT(...) |
| 23 | local str="" | 23 | local str="" |
| @@ -29,8 +29,8 @@ local function PRINT(...) | |||
| 29 | end | 29 | end |
| 30 | end | 30 | end |
| 31 | 31 | ||
| 32 | local gc_cb = function( name_, status_) | 32 | local gc_cb = function(name_, status_) |
| 33 | PRINT( " ---> lane '" .. name_ .. "' collected with status " .. status_) | 33 | PRINT(" ---> lane '" .. name_ .. "' collected with status '" .. status_ .. "'") |
| 34 | end | 34 | end |
| 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 | -- |
| 44 | local function subtable( a, b ) | 44 | local 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 | -- |
| 62 | tables_match= function( a, b ) | 62 | tables_match= function(a, b) |
| 63 | return subtable( a, b ) and subtable( b, a ) | 63 | return subtable(a, b) and subtable(b, a) |
| 64 | end | 64 | end |
| 65 | 65 | ||
| 66 | -- ################################################################################################## | 66 | -- ################################################################################################## |
| 67 | -- ################################################################################################## | 67 | -- ################################################################################################## |
| 68 | -- ################################################################################################## | 68 | -- ################################################################################################## |
| 69 | 69 | ||
| 70 | PRINT( "\n\n", "---=== Tasking (basic) ===---", "\n\n") | 70 | PRINT("\n\n", "---=== Tasking (basic) ===---", "\n\n") |
| 71 | 71 | ||
| 72 | local function task( a, b, c ) | 72 | local 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 |
| 81 | end | 81 | end |
| 82 | 82 | ||
| 83 | local task_launch= lanes_gen( "", { globals={hey=true}, gc_cb = gc_cb}, task ) | 83 | local 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 | ||
| 88 | local lane1= task_launch( 100,200,3 ) | 88 | local lane1= task_launch(100,200,3) |
| 89 | local lane2= task_launch( 200,300,4 ) | 89 | local 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 | ||
| 93 | local st1,st2= lane1.status, lane2.status | 93 | local st1,st2= lane1.status, lane2.status |
| 94 | PRINT(st1,st2) | 94 | PRINT(st1,st2) |
| 95 | assert( st1=="pending" or st1=="running" or st1=="done" ) | 95 | assert(st1=="pending" or st1=="running" or st1=="done") |
| 96 | assert( st2=="pending" or st2=="running" or st2=="done" ) | 96 | assert(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...") | |||
| 101 | local v1, v1_hey= lane1[1], lane1[2] | 101 | local v1, v1_hey= lane1[1], lane1[2] |
| 102 | local v2, v2_hey= lane2[1], lane2[2] | 102 | local v2, v2_hey= lane2[1], lane2[2] |
| 103 | 103 | ||
| 104 | PRINT( v1, v1_hey ) | 104 | PRINT(v1, v1_hey) |
| 105 | assert( v1_hey == true ) | 105 | assert(v1_hey == true) |
| 106 | 106 | ||
| 107 | PRINT( v2, v2_hey ) | 107 | PRINT(v2, v2_hey) |
| 108 | assert( v2_hey == true ) | 108 | assert(v2_hey == true) |
| 109 | 109 | ||
| 110 | assert( lane1.status == "done" ) | 110 | assert(lane1.status == "done") |
| 111 | assert( lane1.status == "done" ) | 111 | assert(lane1.status == "done") |
| 112 | lane1, lane2 = nil | 112 | lane1, lane2 = nil |
| 113 | collectgarbage() | 113 | collectgarbage() |
| 114 | 114 | ||
| @@ -116,9 +116,9 @@ collectgarbage() | |||
| 116 | -- ################################################################################################## | 116 | -- ################################################################################################## |
| 117 | -- ################################################################################################## | 117 | -- ################################################################################################## |
| 118 | 118 | ||
| 119 | PRINT( "\n\n", "---=== Tasking (cancelling) ===---", "\n\n") | 119 | PRINT("\n\n", "---=== Tasking (cancelling) ===---", "\n\n") |
| 120 | 120 | ||
| 121 | local task_launch2= lanes_gen( "", { globals={hey=true}, gc_cb = gc_cb}, task ) | 121 | local task_launch2= lanes_gen("", { globals={hey=true}, gc_cb = gc_cb}, task) |
| 122 | 122 | ||
| 123 | local N=999999999 | 123 | local N=999999999 |
| 124 | local lane9= task_launch2(1,N,1) -- huuuuuuge... | 124 | local lane9= task_launch2(1,N,1) -- huuuuuuge... |
| @@ -129,7 +129,7 @@ local st | |||
| 129 | local t0= os.time() | 129 | local t0= os.time() |
| 130 | while os.time()-t0 < 5 do | 130 | while 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 |
| 134 | end | 134 | end |
| 135 | PRINT(" "..st) | 135 | PRINT(" "..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 |
| 139 | end | 139 | end |
| 140 | if st=="done" then | 140 | if 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)") |
| 142 | end | 142 | end |
| 143 | assert( st=="running" ) | 143 | assert(st=="running") |
| 144 | 144 | ||
| 145 | lane9:cancel( "count", 100) -- 0 timeout, 100 instructions count hook | 145 | lane9:cancel("count", 100) -- 0 timeout, 100 instructions count hook |
| 146 | 146 | ||
| 147 | local t0= os.time() | 147 | local t0= os.time() |
| 148 | while os.time()-t0 < 5 do | 148 | while 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 |
| 152 | end | 152 | end |
| 153 | PRINT(" "..st) | 153 | PRINT(" "..st) |
| 154 | assert( st == "cancelled" ) | 154 | assert(st == "cancelled") |
| 155 | 155 | ||
| 156 | -- cancellation of lanes waiting on a linda | 156 | -- cancellation of lanes waiting on a linda |
| 157 | local limited = lanes.linda("limited") | 157 | local limited = lanes.linda("limited") |
| 158 | limited:limit( "key", 1) | 158 | limited:limit("key", 1) |
| 159 | -- [[################################################ | 159 | -- [[################################################ |
| 160 | limited:send( "key", "hello") -- saturate linda | 160 | limited:send("key", "hello") -- saturate linda |
| 161 | for k, v in pairs( limited:dump()) do | 161 | for k, v in pairs(limited:dump()) do |
| 162 | PRINT("limited[" .. tostring( k) .. "] = " .. tostring( v)) | 162 | PRINT("limited[" .. tostring(k) .. "] = " .. tostring(v)) |
| 163 | end | 163 | end |
| 164 | local wait_send = function() | 164 | local 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 |
| 168 | end | 168 | end |
| 169 | 169 | ||
| 170 | local wait_send_lane = lanes.gen( "*", wait_send)() | 170 | local wait_send_lane = lanes.gen("*", wait_send)() |
| 171 | repeat until wait_send_lane.status == "waiting" | 171 | repeat until wait_send_lane.status == "waiting" |
| 172 | print "wait_send_lane is waiting" | 172 | print "wait_send_lane is waiting" |
| 173 | wait_send_lane:cancel() -- hard cancel, 0 timeout | 173 | wait_send_lane:cancel() -- hard cancel, 0 timeout |
| @@ -176,11 +176,11 @@ print "wait_send_lane is cancelled" | |||
| 176 | --################################################]] | 176 | --################################################]] |
| 177 | local wait_receive = function() | 177 | local 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 |
| 181 | end | 181 | end |
| 182 | 182 | ||
| 183 | local wait_receive_lane = lanes.gen( "*", wait_receive)() | 183 | local wait_receive_lane = lanes.gen("*", wait_receive)() |
| 184 | repeat until wait_receive_lane.status == "waiting" | 184 | repeat until wait_receive_lane.status == "waiting" |
| 185 | print "wait_receive_lane is waiting" | 185 | print "wait_receive_lane is waiting" |
| 186 | wait_receive_lane:cancel() -- hard cancel, 0 timeout | 186 | wait_receive_lane:cancel() -- hard cancel, 0 timeout |
| @@ -189,11 +189,11 @@ print "wait_receive_lane is cancelled" | |||
| 189 | --################################################]] | 189 | --################################################]] |
| 190 | local wait_receive_batched = function() | 190 | local 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 |
| 194 | end | 194 | end |
| 195 | 195 | ||
| 196 | local wait_receive_batched_lane = lanes.gen( "*", wait_receive_batched)() | 196 | local wait_receive_batched_lane = lanes.gen("*", wait_receive_batched)() |
| 197 | repeat until wait_receive_batched_lane.status == "waiting" | 197 | repeat until wait_receive_batched_lane.status == "waiting" |
| 198 | print "wait_receive_batched_lane is waiting" | 198 | print "wait_receive_batched_lane is waiting" |
| 199 | wait_receive_batched_lane:cancel() -- hard cancel, 0 timeout | 199 | wait_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 | ||
| 208 | PRINT( "\n\n", "---=== Communications ===---", "\n\n") | 208 | PRINT("\n\n", "---=== Communications ===---", "\n\n") |
| 209 | 209 | ||
| 210 | local function WR(...) io.stderr:write(...) end | 210 | local function WR(...) io.stderr:write(...) end |
| 211 | 211 | ||
| 212 | local chunk= function( linda ) | 212 | local 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") |
| 235 | end | 236 | end |
| 236 | 237 | ||
| 237 | local linda= lanes_linda("communications") | 238 | local linda = lanes_linda("communications") |
| 238 | assert( type(linda) == "userdata" ) | 239 | assert(type(linda) == "userdata" and tostring(linda) == "Linda: communications") |
| 239 | -- | 240 | -- |
| 240 | -- ["->"] master -> slave | 241 | -- ["->"] master -> slave |
| 241 | -- ["<-"] slave <- master | 242 | -- ["<-"] slave <- master |
| 242 | 243 | ||
| 243 | local function PEEK() return linda:get("<-") end | 244 | local function PEEK() return linda:get("<-") end |
| 244 | local function SEND(...) linda:send( "->", ... ) end | 245 | local function SEND(...) linda:send("->", ...) end |
| 245 | local function RECEIVE() local k,v = linda:receive( 1, "<-" ) return v end | 246 | local function RECEIVE() local k,v = linda:receive(1, "<-") return v end |
| 246 | 247 | ||
| 247 | local t= lanes_gen("io", {gc_cb = gc_cb}, chunk)(linda) -- prepare & launch | 248 | local comms_lane = lanes_gen("io", {gc_cb = gc_cb, name = "auto"}, chunk)(linda) -- prepare & launch |
| 248 | 249 | ||
| 249 | SEND(1); WR( "1 sent\n" ) | 250 | SEND(1); WR("1 sent\n") |
| 250 | SEND(2); WR( "2 sent\n" ) | 251 | SEND(2); WR("2 sent\n") |
| 252 | SEND(3); WR("3 sent\n") | ||
| 251 | for i=1,100 do | 253 | for 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 | ||
| 254 | end | 257 | end |
| 255 | SEND(3); WR( "3 sent\n" ) | 258 | SEND(nil); WR("\nnil sent\n") |
| 256 | 259 | ||
| 257 | local a,b,c= RECEIVE(), RECEIVE(), RECEIVE() | 260 | local a,b,c = RECEIVE(), RECEIVE(), RECEIVE() |
| 258 | 261 | ||
| 259 | print( "lane status: " .. t.status) | 262 | print("lane status: " .. comms_lane.status) |
| 260 | if t.status == "error" then | 263 | if comms_lane.status == "error" then |
| 261 | print( t:join()) | 264 | print(comms_lane:join()) |
| 262 | else | 265 | else |
| 263 | WR( a..", "..b..", "..c.." received\n" ) | 266 | WR(a..", "..b..", "..c.." received\n") |
| 264 | end | 267 | end |
| 265 | 268 | ||
| 266 | assert( a==1 and b==2 and c==3 ) | 269 | assert(a==1 and b==2 and c==3) |
| 267 | 270 | ||
| 268 | local a= RECEIVE(); WR( a.." received\n" ) | 271 | local a = RECEIVE(); WR(a.." received\n") |
| 269 | assert( a=='a' ) | 272 | assert(a=='a') |
| 270 | 273 | ||
| 271 | local a= RECEIVE(); WR( type(a).." received\n" ) | 274 | local null = RECEIVE(); WR(tostring(null).." received\n") |
| 272 | assert( tables_match( a, {'a','b','c',d=10} ) ) | 275 | assert(null==nil) |
| 273 | 276 | ||
| 274 | assert( PEEK() == nil ) | 277 | local out_t = RECEIVE(); WR(type(out_t).." received\n") |
| 278 | assert(tables_match(out_t, {'a','b','c',d=10})) | ||
| 279 | |||
| 280 | assert(PEEK() == nil) | ||
| 275 | SEND(4) | 281 | SEND(4) |
| 276 | 282 | ||
| 277 | local complex_table = RECEIVE(); WR( type(complex_table).." received\n" ) | 283 | local complex_table = RECEIVE(); WR(type(complex_table).." received\n") |
| 278 | assert( complex_table[1] == complex_table[3] and complex_table[2] == complex_table[4]) | 284 | assert(complex_table[1] == complex_table[3] and complex_table[2] == complex_table[4]) |
| 279 | WR( table.concat( {complex_table[1][1],complex_table[2][1],complex_table[3][1],complex_table[4][1]},", ")) | 285 | WR(table.concat({complex_table[1][1],complex_table[2][1],complex_table[3][1],complex_table[4][1]},", ")) |
| 280 | 286 | ||
| 281 | WR("collectgarbage") | 287 | WR("collectgarbage") |
| 282 | t = nil | 288 | comms_lane = nil |
| 283 | collectgarbage() | 289 | collectgarbage() |
| 284 | -- wait | 290 | -- wait |
| 285 | WR("waiting 1s") | 291 | WR("waiting 1s") |
| 286 | linda:receive( 1, "wait") | 292 | lanes.sleep(1) |
| 287 | 293 | ||
| 288 | -- ################################################################################################## | 294 | -- ################################################################################################## |
| 289 | -- ################################################################################################## | 295 | -- ################################################################################################## |
| 290 | -- ################################################################################################## | 296 | -- ################################################################################################## |
| 291 | 297 | ||
| 292 | PRINT( "\n\n", "---=== Stdlib naming ===---", "\n\n") | 298 | PRINT("\n\n", "---=== Stdlib naming ===---", "\n\n") |
| 293 | 299 | ||
| 294 | local function dump_g( _x) | 300 | local 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 |
| 302 | end | 308 | end |
| 303 | 309 | ||
| 304 | local function io_os_f( _x) | 310 | local 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 |
| 311 | end | 317 | end |
| 312 | 318 | ||
| 313 | local function coro_f( _x) | 319 | local 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 |
| 319 | end | 325 | end |
| 320 | 326 | ||
| 321 | assert.fails( function() lanes_gen( "xxx", {gc_cb = gc_cb}, io_os_f ) end ) | 327 | assert.fails(function() lanes_gen("xxx", {gc_cb = gc_cb}, io_os_f) end) |
| 322 | 328 | ||
| 323 | local stdlib_naming_tests = | 329 | local 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 | ||
| 336 | for _, t in ipairs( stdlib_naming_tests) do | 342 | for _, 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]) |
| 339 | end | 345 | end |
| 340 | 346 | ||
| 341 | WR("collectgarbage") | 347 | WR("collectgarbage") |
| @@ -345,17 +351,17 @@ collectgarbage() | |||
| 345 | -- ################################################################################################## | 351 | -- ################################################################################################## |
| 346 | -- ################################################################################################## | 352 | -- ################################################################################################## |
| 347 | 353 | ||
| 348 | PRINT( "\n\n", "---=== Comms criss cross ===---", "\n\n") | 354 | PRINT("\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 | -- |
| 352 | local tc= lanes_gen( "io", {gc_cb = gc_cb}, | 358 | local 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 | ||
| 381 | PRINT( "\n\n", "---=== Receive & send of code ===---", "\n\n") | 387 | PRINT("\n\n", "---=== Receive & send of code ===---", "\n\n") |
| 382 | 388 | ||
| 383 | local upvalue="123" | 389 | local upvalue="123" |
| 384 | 390 | ||
| 385 | local function chunk2( linda ) | 391 | local 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") |
| 413 | end | 419 | end |
| 414 | 420 | ||
| 415 | local linda= lanes.linda("linda") | 421 | local linda= lanes.linda("linda") |
| 416 | local t2= lanes_gen( "debug,string,io", {gc_cb = gc_cb}, chunk2 )(linda) -- prepare & launch | 422 | local t2= lanes_gen("debug,string,io", {gc_cb = gc_cb}, chunk2)(linda) -- prepare & launch |
| 417 | linda:send( "down", function(linda) linda:send( "up", "ready!" ) end, | 423 | linda: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 | -- |
| 421 | local k,s= linda:receive( 1, "up" ) | 427 | local k,s= linda:receive(1, "up") |
| 422 | if t2.status == "error" then | 428 | if t2.status == "error" then |
| 423 | print( "t2 error: " , t2:join()) | 429 | print("t2 error: " , t2:join()) |
| 424 | end | 430 | end |
| 425 | PRINT(s) | 431 | PRINT(s) |
| 426 | assert( s=="ready!" ) | 432 | assert(s=="ready!") |
| 427 | 433 | ||
| 428 | -- returns of the 'chunk2' itself | 434 | -- returns of the 'chunk2' itself |
| 429 | -- | 435 | -- |
| 430 | local k,f= linda:receive( "up" ) | 436 | local k,f= linda:receive("up") |
| 431 | assert( type(f)=="function" ) | 437 | assert(type(f)=="function") |
| 432 | 438 | ||
| 433 | local s2= f() | 439 | local s2= f() |
| 434 | assert( s2==":)" ) | 440 | assert(s2==":)") |
| 435 | 441 | ||
| 436 | local k,ok2= linda:receive( "up" ) | 442 | local k,ok2= linda:receive("up") |
| 437 | assert( ok2 == "ok2" ) | 443 | assert(ok2 == "ok2") |
| 438 | 444 | ||
| 439 | -- ################################################################################################## | 445 | -- ################################################################################################## |
| 440 | -- ################################################################################################## | 446 | -- ################################################################################################## |
| 441 | -- ################################################################################################## | 447 | -- ################################################################################################## |
| 442 | 448 | ||
| 443 | PRINT( "\n\n", "---=== :join test ===---", "\n\n") | 449 | PRINT("\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 | ||
| 449 | local S= lanes_gen( "table", {gc_cb = gc_cb}, | 455 | local 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) |
| 459 | end ) | 465 | end) |
| 460 | 466 | ||
| 461 | h= S { 12, 13, 14 } -- execution starts, h[1..3] will get the return values | 467 | h= 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 |
| 463 | linda:receive(0.5, "gloupti") | 469 | lanes.sleep(0.5) |
| 464 | print( "joining with '" .. h:get_debug_threadname() .. "'") | 470 | print("joining with '" .. h:get_debug_threadname() .. "'") |
| 465 | local a,b,c,d= h:join() | 471 | local a,b,c,d= h:join() |
| 466 | if h.status == "error" then | 472 | if 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) |
| 468 | else | 474 | else |
| 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) |
| 474 | end | 480 | end |
| 475 | 481 | ||
| 476 | local nameof_type, nameof_name = lanes.nameof( print) | 482 | local nameof_type, nameof_name = lanes.nameof(print) |
| 477 | PRINT( "name of " .. nameof_type .. " print = '" .. nameof_name .. "'") | 483 | PRINT("name of " .. nameof_type .. " print = '" .. nameof_name .. "'") |
| 478 | 484 | ||
| 479 | -- | 485 | -- |
| 480 | io.stderr:write "Done! :)\n" | 486 | io.stderr:write "Done! :)\n" |
