diff options
-rw-r--r-- | docs/index.html | 18 | ||||
-rw-r--r-- | src/lanes.lua | 38 | ||||
-rw-r--r-- | src/linda.cpp | 19 | ||||
-rw-r--r-- | tests/basic.lua | 11 | ||||
-rw-r--r-- | tests/cancel.lua | 23 | ||||
-rw-r--r-- | tests/deadlock.lua | 7 | ||||
-rw-r--r-- | tests/ehynes.lua | 7 | ||||
-rw-r--r-- | tests/errhangtest.lua | 4 | ||||
-rw-r--r-- | tests/nameof.lua | 9 | ||||
-rw-r--r-- | tests/objects.lua | 34 | ||||
-rw-r--r-- | tests/protect_allocator.lua | 9 | ||||
-rw-r--r-- | tests/timer.lua | 2 | ||||
-rw-r--r-- | tests/track_lanes.lua | 12 |
13 files changed, 126 insertions, 67 deletions
diff --git a/docs/index.html b/docs/index.html index 0d97c29..98c2abb 100644 --- a/docs/index.html +++ b/docs/index.html | |||
@@ -1198,9 +1198,9 @@ | |||
1198 | 1198 | ||
1199 | [true|lanes.cancel_error] = h:send([timeout_secs,] key, ...) | 1199 | [true|lanes.cancel_error] = h:send([timeout_secs,] key, ...) |
1200 | 1200 | ||
1201 | [key, val]|[lanes.cancel_error] = h:receive([timeout_secs,] key [, ...]) | 1201 | key, val = h:receive([timeout_secs,] key [, key...]) |
1202 | 1202 | ||
1203 | [key, val [, ...]]|[lanes.cancel_error] = h:receive(timeout, h.batched, key, n_uint_min[, n_uint_max]) | 1203 | key, val [, val...] = h:receive(timeout, h.batched, key, n_uint_min[, n_uint_max]) |
1204 | 1204 | ||
1205 | [true|lanes.cancel_error] = h:limit(key, n_uint) | 1205 | [true|lanes.cancel_error] = h:limit(key, n_uint) |
1206 | </pre></td></tr></table> | 1206 | </pre></td></tr></table> |
@@ -1235,9 +1235,9 @@ | |||
1235 | </p> | 1235 | </p> |
1236 | 1236 | ||
1237 | <p> | 1237 | <p> |
1238 | Equally, <tt>receive()</tt> returns a key and the value extracted from it, or nothing for timeout. Note that <tt>nil</tt>s can be sent and received; the <tt>key</tt> value will tell it apart from a timeout. | 1238 | Equally, <tt>receive()</tt> returns a key and the value extracted from it. Note that <tt>nil</tt>s can be sent and received; the <tt>key</tt> value will tell it apart from a timeout.<br/> |
1239 | <br/> | 1239 | <tt>receive()</tt> returns <tt>nil, lanes.cancel_error</tt> if interrupted by a hard cancel request.<br/> |
1240 | <tt>receive()</tt> returns <tt>lanes.cancel_error</tt> if interrupted by a soft cancel request. | 1240 | <tt>receive()</tt> returns <tt>nil, "timeout"</tt> if nothing was available. |
1241 | </p> | 1241 | </p> |
1242 | 1242 | ||
1243 | <p> | 1243 | <p> |
@@ -1439,16 +1439,18 @@ On the other side, you need to use a common Linda for waiting for multiple keys. | |||
1439 | </pre></td></tr></table> | 1439 | </pre></td></tr></table> |
1440 | 1440 | ||
1441 | <p> | 1441 | <p> |
1442 | The full list of active timers can be obtained. Obviously, this is a snapshot, and non-repeating timers might no longer exist by the time the results are inspected. | 1442 | The full list of active timers can be obtained. Obviously, this is a snapshot, and non-repeating timers might no longer exist by the time the results are inspected.<br /> |
1443 | Can return <tt>nil, "timeout"</tt> or <tt>nil, lanes.cancel_error</tt> in case of interruption. | ||
1443 | </p> | 1444 | </p> |
1444 | 1445 | ||
1445 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | 1446 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> |
1446 | void = lanes.sleep(['indefinitely'|seconds|nil]) | 1447 | nil, "timeout" = lanes.sleep(['indefinitely'|seconds|nil]) |
1447 | </pre></td></tr></table> | 1448 | </pre></td></tr></table> |
1448 | 1449 | ||
1449 | <p> | 1450 | <p> |
1450 | A very simple way of sleeping when nothing else is available. Is implemented by attempting to read some data in an unused channel of the internal linda used for timers (this linda exists even when timers aren't enabled). | 1451 | A very simple way of sleeping when nothing else is available. Is implemented by attempting to read some data in an unused channel of the internal linda used for timers (this linda exists even when timers aren't enabled). |
1451 | Default duration is 0, which should only cause a thread context switch. | 1452 | Default duration is 0, which should only cause a thread context switch.<br /> |
1453 | Return values should always be <tt>nil, "timeout"</tt> (or <tt>nil, lanes.cancel_error</tt> in case of interruption). | ||
1452 | </p> | 1454 | </p> |
1453 | 1455 | ||
1454 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> | 1456 | <table border="1" bgcolor="#E0E0FF" cellpadding="10" style="width:50%"><tr><td><pre> |
diff --git a/src/lanes.lua b/src/lanes.lua index d5a04e5..f5e81d4 100644 --- a/src/lanes.lua +++ b/src/lanes.lua | |||
@@ -573,20 +573,22 @@ local configure_timers = function() | |||
573 | secs = next_wakeup - now_secs() | 573 | secs = next_wakeup - now_secs() |
574 | if secs < 0 then secs = 0 end | 574 | if secs < 0 then secs = 0 end |
575 | end | 575 | end |
576 | local key, what = timerLinda:receive(secs, TGW_KEY, TGW_QUERY) | 576 | -- poll both TGW_KEY and TGW_QUERY at the same time |
577 | local _timerKey, _what = timerLinda:receive(secs, TGW_KEY, TGW_QUERY) | ||
577 | 578 | ||
578 | if key == TGW_KEY then | 579 | if _timerKey == TGW_KEY then |
579 | assert(getmetatable(what) == "Linda") -- 'what' should be a linda on which the client sets a timer | 580 | assert(getmetatable(_what) == "Linda") -- '_what' should be a linda on which the client sets a timer |
580 | local _, key, wakeup_at, period = timerLinda:receive(0, timer_gateway_batched, TGW_KEY, 3) | 581 | local _, key, wakeup_at, period = timerLinda:receive(0, timer_gateway_batched, TGW_KEY, 3) |
581 | assert(key) | 582 | assert(key) |
582 | set_timer(what, key, wakeup_at, period and period > 0 and period or nil) | 583 | set_timer(_what, key, wakeup_at, period and period > 0 and period or nil) |
583 | elseif key == TGW_QUERY then | 584 | elseif _timerKey == TGW_QUERY then |
584 | if what == "get_timers" then | 585 | if _what == "get_timers" then |
585 | timerLinda:send(TGW_REPLY, get_timers()) | 586 | timerLinda:send(TGW_REPLY, get_timers()) |
586 | else | 587 | else |
587 | timerLinda:send(TGW_REPLY, "unknown query " .. what) | 588 | timerLinda:send(TGW_REPLY, "unknown query " .. _what) |
588 | end | 589 | end |
589 | --elseif secs == nil then -- got no value while block-waiting? | 590 | else -- got no value while block-waiting |
591 | assert(_what == cancel_error or _what == "timeout") | ||
590 | -- WR("timer lane: no linda, aborted?") | 592 | -- WR("timer lane: no linda, aborted?") |
591 | end | 593 | end |
592 | end | 594 | end |
@@ -630,8 +632,14 @@ local configure_timers = function() | |||
630 | -- PUBLIC LANES API | 632 | -- PUBLIC LANES API |
631 | timers = function() | 633 | timers = function() |
632 | timerLinda:send(TGW_QUERY, "get_timers") | 634 | timerLinda:send(TGW_QUERY, "get_timers") |
633 | local _, r = timerLinda:receive(TGW_REPLY) | 635 | -- can be nil, <something> in case of cancellation or timeout |
634 | return r | 636 | local _k, _t = timerLinda:receive(TGW_REPLY) |
637 | -- success: return the table | ||
638 | if _k then | ||
639 | return _t | ||
640 | end | ||
641 | -- error: return everything we got | ||
642 | return _k, _t | ||
635 | end -- timers() | 643 | end -- timers() |
636 | end -- configure_timers() | 644 | end -- configure_timers() |
637 | 645 | ||
@@ -639,7 +647,7 @@ end -- configure_timers() | |||
639 | -- ###################################### lanes.sleep() ############################################ | 647 | -- ###################################### lanes.sleep() ############################################ |
640 | -- ################################################################################################# | 648 | -- ################################################################################################# |
641 | 649 | ||
642 | -- <void> = sleep([seconds_]) | 650 | -- nil, "timeout" = sleep([seconds_]) |
643 | -- | 651 | -- |
644 | -- PUBLIC LANES API | 652 | -- PUBLIC LANES API |
645 | local sleep = function(seconds_) | 653 | local sleep = function(seconds_) |
@@ -699,9 +707,9 @@ local genlock = function(linda_, key_, N) | |||
699 | -- 'nil' timeout allows 'key_' to be numeric | 707 | -- 'nil' timeout allows 'key_' to be numeric |
700 | return linda_:send(timeout, key_, true) -- suspends until been able to push them | 708 | return linda_:send(timeout, key_, true) -- suspends until been able to push them |
701 | else | 709 | else |
702 | local k = linda_:receive(nil, key_) | 710 | local _k, _v = linda_:receive(nil, key_) |
703 | -- propagate cancel_error if we got it, else return true or false | 711 | -- propagate cancel_error if we got it, else return true or false |
704 | return k and ((k ~= cancel_error) and true or k) or false | 712 | return (_v == cancel_error and _v) or (_k and true or false) |
705 | end | 713 | end |
706 | end | 714 | end |
707 | or | 715 | or |
@@ -711,9 +719,9 @@ local genlock = function(linda_, key_, N) | |||
711 | -- 'nil' timeout allows 'key_' to be numeric | 719 | -- 'nil' timeout allows 'key_' to be numeric |
712 | return linda_:send(timeout, key_, trues(M_)) -- suspends until been able to push them | 720 | return linda_:send(timeout, key_, trues(M_)) -- suspends until been able to push them |
713 | else | 721 | else |
714 | local k = linda_:receive(nil, linda_.batched, key_, -M_) | 722 | local _k, _v = linda_:receive(nil, linda_.batched, key_, -M_) |
715 | -- propagate cancel_error if we got it, else return true or false | 723 | -- propagate cancel_error if we got it, else return true or false |
716 | return k and ((k ~= cancel_error) and true or k) or false | 724 | return (_v == cancel_error and _v) or (_k and true or false) |
717 | end | 725 | end |
718 | end | 726 | end |
719 | end -- genlock | 727 | end -- genlock |
diff --git a/src/linda.cpp b/src/linda.cpp index 4ab89ab..2a31799 100644 --- a/src/linda.cpp +++ b/src/linda.cpp | |||
@@ -553,17 +553,30 @@ LUAG_FUNC(linda_receive) | |||
553 | } | 553 | } |
554 | 554 | ||
555 | switch (_cancel) { | 555 | switch (_cancel) { |
556 | case CancelRequest::None: | ||
557 | { | ||
558 | int const _nbPushed{ _pushed.value() }; | ||
559 | if (_nbPushed == 0) { | ||
560 | // not enough data in the linda slot to fulfill the request, return nil, "timeout" | ||
561 | lua_pushnil(L_); | ||
562 | std::ignore = lua_pushstringview(L_, "timeout"); | ||
563 | return 2; | ||
564 | } | ||
565 | return _nbPushed; | ||
566 | } | ||
567 | |||
556 | case CancelRequest::Soft: | 568 | case CancelRequest::Soft: |
557 | // if user wants to soft-cancel, the call returns kCancelError | 569 | // if user wants to soft-cancel, the call returns nil, kCancelError |
570 | lua_pushnil(L_); | ||
558 | kCancelError.pushKey(L_); | 571 | kCancelError.pushKey(L_); |
559 | return 1; | 572 | return 2; |
560 | 573 | ||
561 | case CancelRequest::Hard: | 574 | case CancelRequest::Hard: |
562 | // raise an error interrupting execution only in case of hard cancel | 575 | // raise an error interrupting execution only in case of hard cancel |
563 | raise_cancel_error(L_); // raises an error and doesn't return | 576 | raise_cancel_error(L_); // raises an error and doesn't return |
564 | 577 | ||
565 | default: | 578 | default: |
566 | return _pushed.value(); | 579 | raise_luaL_error(L_, "internal error: unknown cancel request"); |
567 | } | 580 | } |
568 | }; | 581 | }; |
569 | return Linda::ProtectedCall(L_, _receive); | 582 | return Linda::ProtectedCall(L_, _receive); |
diff --git a/tests/basic.lua b/tests/basic.lua index ab8a080..da7d756 100644 --- a/tests/basic.lua +++ b/tests/basic.lua | |||
@@ -29,6 +29,11 @@ local function PRINT(...) | |||
29 | end | 29 | end |
30 | end | 30 | end |
31 | 31 | ||
32 | local SLEEP = function(...) | ||
33 | local k, v = lanes.sleep(...) | ||
34 | assert(k == nil and v == "timeout") | ||
35 | end | ||
36 | |||
32 | local gc_cb = function(name_, status_) | 37 | local gc_cb = function(name_, status_) |
33 | PRINT(" ---> lane '" .. name_ .. "' collected with status '" .. status_ .. "'") | 38 | PRINT(" ---> lane '" .. name_ .. "' collected with status '" .. status_ .. "'") |
34 | end | 39 | end |
@@ -256,7 +261,7 @@ SEND(3); WR("main ", "3 sent\n") | |||
256 | SEND(setmetatable({"should be ignored"},{__lanesignore=true})); WR("main ", "__lanesignore table sent\n") | 261 | SEND(setmetatable({"should be ignored"},{__lanesignore=true})); WR("main ", "__lanesignore table sent\n") |
257 | for i=1,100 do | 262 | for i=1,100 do |
258 | WR "." | 263 | WR "." |
259 | lanes.sleep(0.0001) | 264 | SLEEP(0.0001) |
260 | assert(PEEK() == nil) -- nothing coming in, yet | 265 | assert(PEEK() == nil) -- nothing coming in, yet |
261 | end | 266 | end |
262 | SEND(nil); WR("\nmain ", "nil sent\n") | 267 | SEND(nil); WR("\nmain ", "nil sent\n") |
@@ -293,7 +298,7 @@ comms_lane = nil | |||
293 | collectgarbage() | 298 | collectgarbage() |
294 | -- wait | 299 | -- wait |
295 | WR("waiting 1s") | 300 | WR("waiting 1s") |
296 | lanes.sleep(1) | 301 | SLEEP(1) |
297 | 302 | ||
298 | -- ################################################################################################## | 303 | -- ################################################################################################## |
299 | -- ################################################################################################## | 304 | -- ################################################################################################## |
@@ -470,7 +475,7 @@ end) | |||
470 | 475 | ||
471 | h= S { 12, 13, 14 } -- execution starts, h[1..3] will get the return values | 476 | h= S { 12, 13, 14 } -- execution starts, h[1..3] will get the return values |
472 | -- wait a bit so that the lane has a chance to set its debug name | 477 | -- wait a bit so that the lane has a chance to set its debug name |
473 | lanes.sleep(0.5) | 478 | SLEEP(0.5) |
474 | print("joining with '" .. h:get_debug_threadname() .. "'") | 479 | print("joining with '" .. h:get_debug_threadname() .. "'") |
475 | local a,b,c,d= h:join() | 480 | local a,b,c,d= h:join() |
476 | if h.status == "error" then | 481 | if h.status == "error" then |
diff --git a/tests/cancel.lua b/tests/cancel.lua index e39ad98..b75d085 100644 --- a/tests/cancel.lua +++ b/tests/cancel.lua | |||
@@ -9,6 +9,11 @@ end | |||
9 | 9 | ||
10 | local lanes = require "lanes" .configure{ with_timers = false} | 10 | local lanes = require "lanes" .configure{ with_timers = false} |
11 | 11 | ||
12 | local SLEEP = function(...) | ||
13 | local k, v = lanes.sleep(...) | ||
14 | assert(k == nil and v == "timeout") | ||
15 | end | ||
16 | |||
12 | local linda = lanes.linda() | 17 | local linda = lanes.linda() |
13 | -- a numeric value to read | 18 | -- a numeric value to read |
14 | linda:set( "val", 33.0) | 19 | linda:set( "val", 33.0) |
@@ -51,7 +56,7 @@ local waitCancellation = function( h, expected_status) | |||
51 | if expected_status ~= "running" then | 56 | if expected_status ~= "running" then |
52 | repeat | 57 | repeat |
53 | -- print( "lane status:", h.status) | 58 | -- print( "lane status:", h.status) |
54 | l:receive( 0.1, "yeah") -- wait a bit | 59 | SLEEP(0.1) -- wait a bit |
55 | until h.status ~= "running" | 60 | until h.status ~= "running" |
56 | end | 61 | end |
57 | print( "lane status:", h.status) | 62 | print( "lane status:", h.status) |
@@ -80,8 +85,8 @@ local laneBody = function( mode_, payload_) | |||
80 | -- linda mode | 85 | -- linda mode |
81 | io.stdout:write( " lane calling receive() ... ") | 86 | io.stdout:write( " lane calling receive() ... ") |
82 | local key, val = linda:receive( payload_, "boob") | 87 | local key, val = linda:receive( payload_, "boob") |
83 | print( lanes.cancel_error == key and "cancel_error" or tostring( key), tostring( val)) | 88 | print(tostring(key), val == lanes.cancel_error and "cancel_error" or tostring(val)) |
84 | if key == lanes.cancel_error then | 89 | if val == lanes.cancel_error then |
85 | break -- gracefully abort loop | 90 | break -- gracefully abort loop |
86 | end | 91 | end |
87 | elseif mode_ == "get" then | 92 | elseif mode_ == "get" then |
@@ -138,9 +143,9 @@ if not next(which_tests) or which_tests.linda then | |||
138 | h = lanes.gen( "*", laneBody)( "receive", nil) -- start an infinite wait on the linda | 143 | h = lanes.gen( "*", laneBody)( "receive", nil) -- start an infinite wait on the linda |
139 | 144 | ||
140 | print "wait 1s" | 145 | print "wait 1s" |
141 | linda:receive( 1, "yeah") | 146 | SLEEP(1) |
142 | 147 | ||
143 | -- linda cancel: linda:receive() returns cancel_error immediately | 148 | -- linda cancel: linda:receive() returns nil,cancel_error immediately |
144 | print "cancelling" | 149 | print "cancelling" |
145 | linda:cancel( "both") | 150 | linda:cancel( "both") |
146 | 151 | ||
@@ -159,7 +164,7 @@ if not next(which_tests) or which_tests.soft then | |||
159 | h = lanes.gen( "*", protectedBody)( "receive") -- start an infinite wait on the linda | 164 | h = lanes.gen( "*", protectedBody)( "receive") -- start an infinite wait on the linda |
160 | 165 | ||
161 | print "wait 1s" | 166 | print "wait 1s" |
162 | linda:receive( 1, "yeah") | 167 | SLEEP(1) |
163 | 168 | ||
164 | -- soft cancel, no awakening of waiting linda operations, should timeout | 169 | -- soft cancel, no awakening of waiting linda operations, should timeout |
165 | local a, b = h:cancel( "soft", 1, false) | 170 | local a, b = h:cancel( "soft", 1, false) |
@@ -182,7 +187,7 @@ if not next(which_tests) or which_tests.hook then | |||
182 | print "\n\n####################################################################\nbegin hook cancel test\n" | 187 | print "\n\n####################################################################\nbegin hook cancel test\n" |
183 | h = lanes.gen( "*", protectedBody)( "get", 300000) | 188 | h = lanes.gen( "*", protectedBody)( "get", 300000) |
184 | print "wait 2s" | 189 | print "wait 2s" |
185 | linda:receive( 2, "yeah") | 190 | SLEEP(2) |
186 | 191 | ||
187 | -- count hook cancel after some instruction instructions | 192 | -- count hook cancel after some instruction instructions |
188 | print "cancelling" | 193 | print "cancelling" |
@@ -201,7 +206,7 @@ if not next(which_tests) or which_tests.hard then | |||
201 | 206 | ||
202 | -- wait 2s before cancelling the lane | 207 | -- wait 2s before cancelling the lane |
203 | print "wait 2s" | 208 | print "wait 2s" |
204 | linda:receive( 2, "yeah") | 209 | SLEEP(2) |
205 | 210 | ||
206 | -- hard cancel: the lane will be interrupted from inside its current linda:receive() and won't return from it | 211 | -- hard cancel: the lane will be interrupted from inside its current linda:receive() and won't return from it |
207 | print "cancelling" | 212 | print "cancelling" |
@@ -220,7 +225,7 @@ if not next(which_tests) or which_tests.hard_unprotected then | |||
220 | 225 | ||
221 | -- wait 2s before cancelling the lane | 226 | -- wait 2s before cancelling the lane |
222 | print "wait 2s" | 227 | print "wait 2s" |
223 | linda:receive( 2, "yeah") | 228 | SLEEP(2) |
224 | 229 | ||
225 | -- hard cancel: the lane will be interrupted from inside its current linda:receive() and won't return from it | 230 | -- hard cancel: the lane will be interrupted from inside its current linda:receive() and won't return from it |
226 | print "cancelling" | 231 | print "cancelling" |
diff --git a/tests/deadlock.lua b/tests/deadlock.lua index c85d99f..c38ca13 100644 --- a/tests/deadlock.lua +++ b/tests/deadlock.lua | |||
@@ -4,6 +4,11 @@ | |||
4 | local lanes = require('lanes').configure{with_timers=false} | 4 | local lanes = require('lanes').configure{with_timers=false} |
5 | local linda = lanes.linda "deadlock_linda" | 5 | local linda = lanes.linda "deadlock_linda" |
6 | 6 | ||
7 | local SLEEP = function(...) | ||
8 | local k, v = lanes.sleep(...) | ||
9 | assert(k == nil and v == "timeout") | ||
10 | end | ||
11 | |||
7 | print "let's begin" | 12 | print "let's begin" |
8 | 13 | ||
9 | local do_extra_stuff = true | 14 | local do_extra_stuff = true |
@@ -35,5 +40,5 @@ end | |||
35 | -- With the bug not fixed, the linda keeper's mutex is still acquired, | 40 | -- With the bug not fixed, the linda keeper's mutex is still acquired, |
36 | -- and the program hangs when the internal linda used for timers attempts to acquire the same keeper (there is only one by default) | 41 | -- and the program hangs when the internal linda used for timers attempts to acquire the same keeper (there is only one by default) |
37 | print('waiting a bit') | 42 | print('waiting a bit') |
38 | lanes.sleep(2) | 43 | SLEEP(2) |
39 | print('we should reach here') \ No newline at end of file | 44 | print('we should reach here') \ No newline at end of file |
diff --git a/tests/ehynes.lua b/tests/ehynes.lua index e203a12..9436c7d 100644 --- a/tests/ehynes.lua +++ b/tests/ehynes.lua | |||
@@ -4,6 +4,11 @@ | |||
4 | local lanes = require "lanes" | 4 | local lanes = require "lanes" |
5 | lanes.configure() | 5 | lanes.configure() |
6 | 6 | ||
7 | local SLEEP = function(...) | ||
8 | local k, v = lanes.sleep(...) | ||
9 | assert(k == nil and v == "timeout") | ||
10 | end | ||
11 | |||
7 | local function PRINT_FMT( fmt, ... ) | 12 | local function PRINT_FMT( fmt, ... ) |
8 | io.stderr:write( string.format(fmt,...).."\n" ) | 13 | io.stderr:write( string.format(fmt,...).."\n" ) |
9 | end | 14 | end |
@@ -36,7 +41,7 @@ local receiver2 = receiver_gen('another message') | |||
36 | 41 | ||
37 | -- a function to pause and log the execution for debugging | 42 | -- a function to pause and log the execution for debugging |
38 | local function logf(s, f, ...) | 43 | local function logf(s, f, ...) |
39 | linda:receive(1, "dummy") -- wait 1s | 44 | SLEEP(1) |
40 | PRINT_FMT( "*** %s", s ) | 45 | PRINT_FMT( "*** %s", s ) |
41 | f(...) | 46 | f(...) |
42 | end | 47 | end |
diff --git a/tests/errhangtest.lua b/tests/errhangtest.lua index 84de8c6..99f44b2 100644 --- a/tests/errhangtest.lua +++ b/tests/errhangtest.lua | |||
@@ -24,8 +24,10 @@ if true then | |||
24 | print "\n#### set 3 -> receive batched" | 24 | print "\n#### set 3 -> receive batched" |
25 | local fun = function() print "function test ok" end | 25 | local fun = function() print "function test ok" end |
26 | print(pcall(linda.set, linda, 'test', true, nil, fun)) | 26 | print(pcall(linda.set, linda, 'test', true, nil, fun)) |
27 | local k,b,n,f = linda:receive(linda.batched, 'test', 3) -- read back the contents | 27 | -- read back the contents |
28 | local k,b,n,f = linda:receive(linda.batched, 'test', 3) | ||
28 | assert(linda:get("test") == nil) | 29 | assert(linda:get("test") == nil) |
30 | -- check they are ok | ||
29 | print(k, b, n) | 31 | print(k, b, n) |
30 | f() | 32 | f() |
31 | print "OK" | 33 | print "OK" |
diff --git a/tests/nameof.lua b/tests/nameof.lua index 58df3e2..f48a971 100644 --- a/tests/nameof.lua +++ b/tests/nameof.lua | |||
@@ -1,5 +1,10 @@ | |||
1 | local lanes = require "lanes".configure{nb_user_keepers = 100, on_state_create = function() end} | 1 | local lanes = require "lanes".configure{nb_user_keepers = 100, on_state_create = function() end} |
2 | 2 | ||
3 | local SLEEP = function(...) | ||
4 | local k, v = lanes.sleep(...) | ||
5 | assert(k == nil and v == "timeout") | ||
6 | end | ||
7 | |||
3 | print("Name of table: ", lanes.nameof({})) | 8 | print("Name of table: ", lanes.nameof({})) |
4 | print("Name of string.sub: ", lanes.nameof(string.sub)) | 9 | print("Name of string.sub: ", lanes.nameof(string.sub)) |
5 | print("Name of print: ", lanes.nameof(print)) | 10 | print("Name of print: ", lanes.nameof(print)) |
@@ -14,12 +19,12 @@ end | |||
14 | 19 | ||
15 | -- start the lane without any library | 20 | -- start the lane without any library |
16 | local h = lanes.gen(nil, body)() | 21 | local h = lanes.gen(nil, body)() |
17 | lanes.sleep(0.1) | 22 | SLEEP(0.1) |
18 | print("Name of lane: ", lanes.nameof(h), "("..h.status..")") | 23 | print("Name of lane: ", lanes.nameof(h), "("..h.status..")") |
19 | assert(h.status == "running") | 24 | assert(h.status == "running") |
20 | -- cancel the lane | 25 | -- cancel the lane |
21 | h:cancel("line", 1) | 26 | h:cancel("line", 1) |
22 | lanes.sleep(0.1) | 27 | SLEEP(0.1) |
23 | print("Name of lane: ", lanes.nameof(h), "("..h.status..")") | 28 | print("Name of lane: ", lanes.nameof(h), "("..h.status..")") |
24 | assert(h.status == "cancelled") | 29 | assert(h.status == "cancelled") |
25 | print "TEST OK" | 30 | print "TEST OK" |
diff --git a/tests/objects.lua b/tests/objects.lua index eed02bf..7668e45 100644 --- a/tests/objects.lua +++ b/tests/objects.lua | |||
@@ -9,27 +9,27 @@ lanes.configure() | |||
9 | 9 | ||
10 | local linda= lanes.linda() | 10 | local linda= lanes.linda() |
11 | 11 | ||
12 | local start_lane= lanes.gen( "io", | 12 | local start_lane= lanes.gen("io", |
13 | function( obj1 ) | 13 | function(obj1 ) |
14 | 14 | ||
15 | assert( obj1.v ) | 15 | assert(obj1.v ) |
16 | assert( obj1.print ) | 16 | assert(obj1.print ) |
17 | 17 | ||
18 | assert( obj1 ) | 18 | assert(obj1 ) |
19 | local mt1= getmetatable(obj1) | 19 | local mt1= getmetatable(obj1) |
20 | assert(mt1) | 20 | assert(mt1) |
21 | 21 | ||
22 | local k, obj2= linda:receive("") | 22 | local k, obj2= linda:receive("") |
23 | assert( obj2 ) | 23 | assert(k == "" and obj2 ) |
24 | local mt2= getmetatable(obj2) | 24 | local mt2= getmetatable(obj2) |
25 | assert(mt2) | 25 | assert(mt2) |
26 | assert( mt1==mt2 ) | 26 | assert(mt1==mt2 ) |
27 | 27 | ||
28 | local v= obj1:print() | 28 | local v= obj1:print() |
29 | assert( v=="aaa" ) | 29 | assert(v=="aaa" ) |
30 | 30 | ||
31 | v= obj2:print() | 31 | v = obj2:print() |
32 | assert( v=="bbb" ) | 32 | assert(v=="bbb" ) |
33 | 33 | ||
34 | return true | 34 | return true |
35 | end | 35 | end |
@@ -37,7 +37,7 @@ local start_lane= lanes.gen( "io", | |||
37 | 37 | ||
38 | 38 | ||
39 | local WR= function(str) | 39 | local WR= function(str) |
40 | io.stderr:write( tostring(str).."\n") | 40 | io.stderr:write(tostring(str).."\n") |
41 | end | 41 | end |
42 | 42 | ||
43 | 43 | ||
@@ -47,7 +47,7 @@ end | |||
47 | -- having the methods 'fixed' in the object tables themselves. | 47 | -- having the methods 'fixed' in the object tables themselves. |
48 | -- | 48 | -- |
49 | local o_mt= { | 49 | local o_mt= { |
50 | __index= function( me, key ) | 50 | __index= function(me, key ) |
51 | if key=="print" then | 51 | if key=="print" then |
52 | return function() WR(me.v); return me.v end | 52 | return function() WR(me.v); return me.v end |
53 | end | 53 | end |
@@ -56,22 +56,22 @@ local o_mt= { | |||
56 | 56 | ||
57 | local function obj_gen(v) | 57 | local function obj_gen(v) |
58 | local o= { v=v } | 58 | local o= { v=v } |
59 | setmetatable( o, o_mt ) | 59 | setmetatable(o, o_mt ) |
60 | return o | 60 | return o |
61 | end | 61 | end |
62 | 62 | ||
63 | local a= obj_gen("aaa") | 63 | local a= obj_gen("aaa") |
64 | local b= obj_gen("bbb") | 64 | local b= obj_gen("bbb") |
65 | 65 | ||
66 | assert( a and b ) | 66 | assert(a and b ) |
67 | 67 | ||
68 | local mt_a= getmetatable(a) | 68 | local mt_a= getmetatable(a) |
69 | local mt_b= getmetatable(b) | 69 | local mt_b= getmetatable(b) |
70 | assert( mt_a and mt_a==mt_b ) | 70 | assert(mt_a and mt_a==mt_b ) |
71 | 71 | ||
72 | local h= start_lane(a) -- 1st object as parameter | 72 | local h= start_lane(a) -- 1st object as parameter |
73 | 73 | ||
74 | linda:send( "", b ) -- 2nd object via Linda | 74 | linda:send("", b ) -- 2nd object via Linda |
75 | 75 | ||
76 | assert( h[1]==true ) -- wait for return | 76 | assert(h[1]==true ) -- wait for return |
77 | 77 | ||
diff --git a/tests/protect_allocator.lua b/tests/protect_allocator.lua index 5cbb1d8..994cb39 100644 --- a/tests/protect_allocator.lua +++ b/tests/protect_allocator.lua | |||
@@ -2,6 +2,11 @@ local print = print | |||
2 | 2 | ||
3 | local lanes = require "lanes".configure{ with_timers = false, allocator="protected"} | 3 | local lanes = require "lanes".configure{ with_timers = false, allocator="protected"} |
4 | 4 | ||
5 | local SLEEP = function(...) | ||
6 | local k, v = lanes.sleep(...) | ||
7 | assert(k == nil and v == "timeout") | ||
8 | end | ||
9 | |||
5 | local linda = lanes.linda() | 10 | local linda = lanes.linda() |
6 | 11 | ||
7 | local body = function( id_) | 12 | local body = function( id_) |
@@ -38,7 +43,7 @@ end | |||
38 | 43 | ||
39 | -- wait a bit | 44 | -- wait a bit |
40 | print "waiting a bit ..." | 45 | print "waiting a bit ..." |
41 | linda:receive( 2, "foo") | 46 | SLEEP(2) |
42 | -- tell lanes to start running | 47 | -- tell lanes to start running |
43 | print "GO!" | 48 | print "GO!" |
44 | for i = 1, COUNT do | 49 | for i = 1, COUNT do |
@@ -49,5 +54,5 @@ end | |||
49 | print "wait for completion" | 54 | print "wait for completion" |
50 | linda:receive( linda.batched, "key", COUNT) | 55 | linda:receive( linda.batched, "key", COUNT) |
51 | print "waiting a bit more ..." | 56 | print "waiting a bit more ..." |
52 | linda:receive( 1, "foo") | 57 | SLEEP(1) |
53 | print "SUCCESS" | 58 | print "SUCCESS" |
diff --git a/tests/timer.lua b/tests/timer.lua index a633286..4da1a50 100644 --- a/tests/timer.lua +++ b/tests/timer.lua | |||
@@ -100,7 +100,7 @@ assert( linda:get(T2) == nil ) | |||
100 | PRINT "...making sure no ticks are coming..." | 100 | PRINT "...making sure no ticks are coming..." |
101 | 101 | ||
102 | local k,v= linda:receive( 10, T1,T2 ) -- should not get any | 102 | local k,v= linda:receive( 10, T1,T2 ) -- should not get any |
103 | assert(v==nil) | 103 | assert(k==nil and v == "timeout") |
104 | 104 | ||
105 | lanes.timer_lane:cancel() -- hard cancel, 0 timeout | 105 | lanes.timer_lane:cancel() -- hard cancel, 0 timeout |
106 | print (lanes.timer_lane[1], lanes.timer_lane[2]) \ No newline at end of file | 106 | print (lanes.timer_lane[1], lanes.timer_lane[2]) \ No newline at end of file |
diff --git a/tests/track_lanes.lua b/tests/track_lanes.lua index daaa94c..5ea9a4e 100644 --- a/tests/track_lanes.lua +++ b/tests/track_lanes.lua | |||
@@ -1,5 +1,9 @@ | |||
1 | local lanes = require "lanes" .configure{ with_timers = false, track_lanes = true} | 1 | local lanes = require "lanes" .configure{ with_timers = false, track_lanes = true} |
2 | local wait = lanes.sleep | 2 | |
3 | local SLEEP = function(...) | ||
4 | local k, v = lanes.sleep(...) | ||
5 | assert(k == nil and v == "timeout") | ||
6 | end | ||
3 | 7 | ||
4 | print "hello" | 8 | print "hello" |
5 | 9 | ||
@@ -43,7 +47,7 @@ g( "forever", 'indefinitely') | |||
43 | g( "two_seconds", 2) | 47 | g( "two_seconds", 2) |
44 | 48 | ||
45 | -- give a bit of time to reach the linda waiting call | 49 | -- give a bit of time to reach the linda waiting call |
46 | wait( 0.1) | 50 | SLEEP(0.1) |
47 | 51 | ||
48 | -- list the known lanes (should be living lanes) | 52 | -- list the known lanes (should be living lanes) |
49 | local threads = track( "============= START", 2) | 53 | local threads = track( "============= START", 2) |
@@ -51,7 +55,7 @@ local threads = track( "============= START", 2) | |||
51 | assert(threads[1].status == 'waiting' and threads[2].status == 'waiting') | 55 | assert(threads[1].status == 'waiting' and threads[2].status == 'waiting') |
52 | 56 | ||
53 | -- wait until "two_seconds has completed" | 57 | -- wait until "two_seconds has completed" |
54 | wait(2.1) | 58 | SLEEP(2.1) |
55 | 59 | ||
56 | local threads = track( "============= two_seconds dead", 2) | 60 | local threads = track( "============= two_seconds dead", 2) |
57 | -- two_seconds forever | 61 | -- two_seconds forever |
@@ -61,7 +65,7 @@ assert(threads[1].status == 'done' and threads[2].status == 'waiting') | |||
61 | g( "two_seconds", 2) | 65 | g( "two_seconds", 2) |
62 | 66 | ||
63 | -- give a bit of time to reach the linda waiting call | 67 | -- give a bit of time to reach the linda waiting call |
64 | wait( 0.1) | 68 | SLEEP( 0.1) |
65 | 69 | ||
66 | -- list the known lanes | 70 | -- list the known lanes |
67 | -- unless garbage collector cleaned it, we should have 3 lanes | 71 | -- unless garbage collector cleaned it, we should have 3 lanes |