aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2024-05-31 17:04:17 +0200
committerBenoit Germain <benoit.germain@ubisoft.com>2024-05-31 17:04:17 +0200
commitf7a38b5681ebf7429828fca9a9f7c109df853d54 (patch)
tree9c4e702071a6915719ca639790936b35ed1ed828 /src
parent95e5bf6461be6e227466911d5e3a683d149df725 (diff)
downloadlanes-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.lua38
-rw-r--r--src/linda.cpp19
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()
636end -- configure_timers() 644end -- 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
645local sleep = function(seconds_) 653local 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
719end -- genlock 727end -- 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);