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); |