diff options
| author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-05-31 17:04:17 +0200 |
|---|---|---|
| committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-05-31 17:04:17 +0200 |
| commit | f7a38b5681ebf7429828fca9a9f7c109df853d54 (patch) | |
| tree | 9c4e702071a6915719ca639790936b35ed1ed828 /src | |
| parent | 95e5bf6461be6e227466911d5e3a683d149df725 (diff) | |
| download | lanes-f7a38b5681ebf7429828fca9a9f7c109df853d54.tar.gz lanes-f7a38b5681ebf7429828fca9a9f7c109df853d54.tar.bz2 lanes-f7a38b5681ebf7429828fca9a9f7c109df853d54.zip | |
Some API changes
* lanes.timers() can return nil, cancel_error if interrupted
* linda:receive() always return a k,v, where k is nil when v is "timeout" or cancel_error
* lanes.sleep returns nil, "timeout" during normal operations
Diffstat (limited to 'src')
| -rw-r--r-- | src/lanes.lua | 38 | ||||
| -rw-r--r-- | src/linda.cpp | 19 |
2 files changed, 39 insertions, 18 deletions
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); |
