diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/keeper.cpp | 47 | ||||
| -rw-r--r-- | src/lanes.lua | 41 | ||||
| -rw-r--r-- | src/linda.cpp | 38 |
3 files changed, 72 insertions, 54 deletions
diff --git a/src/keeper.cpp b/src/keeper.cpp index 7000372..4175d84 100644 --- a/src/keeper.cpp +++ b/src/keeper.cpp | |||
| @@ -123,26 +123,32 @@ KeyUD* KeyUD::GetPtr(KeeperState const K_, int idx_) | |||
| 123 | // ################################################################################################# | 123 | // ################################################################################################# |
| 124 | 124 | ||
| 125 | // in: fifo | 125 | // in: fifo |
| 126 | // out: ...|nothing | 126 | // out: bool ... |
| 127 | // pops the fifo, push as much data as is available (up to the specified count) without consuming it | 127 | // pops the fifo, push bool + as much data as is available (up to the specified count) without consuming it |
| 128 | // bool is true if the requested count was served, else false | ||
| 128 | void KeyUD::peek(KeeperState const K_, int const count_) | 129 | void KeyUD::peek(KeeperState const K_, int const count_) |
| 129 | { | 130 | { |
| 130 | LUA_ASSERT(K_, KeyUD::GetPtr(K_, -1) == this); | 131 | STACK_CHECK_START_ABS(K_, 1); |
| 132 | LUA_ASSERT(K_, KeyUD::GetPtr(K_, -1) == this); // K_: KeyUD | ||
| 131 | if (count <= 0) { // no data is available | 133 | if (count <= 0) { // no data is available |
| 132 | lua_pop(K_, 1); // K_: | 134 | lua_pop(K_, 1); // K_: |
| 135 | lua_pushinteger(K_, 0); // K_: 0 | ||
| 133 | return; | 136 | return; |
| 134 | } | 137 | } |
| 135 | 138 | ||
| 136 | // read <count_> value off the fifo | 139 | // read <count_> value off the fifo, if possible |
| 137 | prepareAccess(K_, -1); // K_: fifo | 140 | prepareAccess(K_, -1); // K_: fifo |
| 138 | int const _at{ lua_gettop(K_) }; | ||
| 139 | int const _count{ std::min(count_, count) }; | 141 | int const _count{ std::min(count_, count) }; |
| 142 | lua_pushinteger(K_, _count); // K_: fifo _count | ||
| 143 | lua_insert(K_, 1); // K_: _count fifo | ||
| 144 | STACK_CHECK(K_, 2); | ||
| 140 | STACK_GROW(K_, _count); | 145 | STACK_GROW(K_, _count); |
| 141 | for (int const _i : std::ranges::iota_view{ 1, _count }) { // push val2 to valN | 146 | for (int const _i : std::ranges::iota_view{ 1, _count }) { // push val2 to valN |
| 142 | lua_rawgeti(K_, 1, first + _i); // K_: fifo val2..N | 147 | lua_rawgeti(K_, 2, first + _i); // K_: _count fifo val2..N |
| 143 | } | 148 | } |
| 144 | lua_rawgeti(K_, 1, first); // push val1 // K_: fifo val2..N val1 | 149 | lua_rawgeti(K_, 2, first); // push val1 // K_: _count fifo val2..N val1 |
| 145 | lua_replace(K_, _at); // replace fifo by val1 to get the output properly ordered // K_: val1..N | 150 | lua_replace(K_, 2); // replace fifo by val1 to get the output properly ordered // K_: _count val1..N |
| 151 | STACK_CHECK(K_, 1 + _count); | ||
| 146 | } | 152 | } |
| 147 | 153 | ||
| 148 | // ################################################################################################# | 154 | // ################################################################################################# |
| @@ -418,7 +424,7 @@ int keepercall_destruct(lua_State* const L_) | |||
| 418 | // ################################################################################################# | 424 | // ################################################################################################# |
| 419 | 425 | ||
| 420 | // in: linda_ud key [count] | 426 | // in: linda_ud key [count] |
| 421 | // out: at most <count> values | 427 | // out: bool + at most <count> values |
| 422 | int keepercall_get(lua_State* const L_) | 428 | int keepercall_get(lua_State* const L_) |
| 423 | { | 429 | { |
| 424 | KeeperState const _K{ L_ }; | 430 | KeeperState const _K{ L_ }; |
| @@ -433,11 +439,13 @@ int keepercall_get(lua_State* const L_) | |||
| 433 | lua_remove(_K, 1); // _K: KeyUD | 439 | lua_remove(_K, 1); // _K: KeyUD |
| 434 | KeyUD* const _key{ KeyUD::GetPtr(_K, -1) }; | 440 | KeyUD* const _key{ KeyUD::GetPtr(_K, -1) }; |
| 435 | if (_key != nullptr) { | 441 | if (_key != nullptr) { |
| 436 | _key->peek(_K, _count); // _K: val... | 442 | _key->peek(_K, _count); // _K: N val... |
| 437 | } else { | 443 | } else { |
| 438 | // no fifo was ever registered for this key, or it is empty | 444 | // no fifo was ever registered for this key, or it is empty |
| 439 | lua_pop(_K, 1); // _K: | 445 | lua_pop(_K, 1); // _K: |
| 446 | lua_pushinteger(_K, 0); // _K: 0 | ||
| 440 | } | 447 | } |
| 448 | LUA_ASSERT(_K, lua_isnumber(_K, 1)); | ||
| 441 | return lua_gettop(_K); | 449 | return lua_gettop(_K); |
| 442 | } | 450 | } |
| 443 | 451 | ||
| @@ -462,13 +470,10 @@ int keepercall_limit(lua_State* const L_) | |||
| 462 | } | 470 | } |
| 463 | // remove any clutter on the stack | 471 | // remove any clutter on the stack |
| 464 | lua_settop(_K, 0); // _K: | 472 | lua_settop(_K, 0); // _K: |
| 465 | if (_key->changeLimit(_limit)) { | 473 | // return true if we decide that blocked threads waiting to write on that key should be awakened |
| 466 | // return true if we decide that blocked threads waiting to write on that key should be awakened | 474 | // this is the case if we detect the key was full but it is no longer the case |
| 467 | // this is the case if we detect the key was full but it is no longer the case | 475 | lua_pushboolean(_K, _key->changeLimit(_limit) ? 1 : 0); // _K: bool |
| 468 | lua_pushboolean(_K, 1); // _K: true | 476 | return 1; |
| 469 | } | ||
| 470 | // return 0 or 1 value | ||
| 471 | return lua_gettop(_K); | ||
| 472 | } | 477 | } |
| 473 | 478 | ||
| 474 | // ################################################################################################# | 479 | // ################################################################################################# |
| @@ -570,7 +575,7 @@ int keepercall_send(lua_State* const L_) | |||
| 570 | // ################################################################################################# | 575 | // ################################################################################################# |
| 571 | 576 | ||
| 572 | // in: linda key [val...] | 577 | // in: linda key [val...] |
| 573 | // out: true if the linda was full but it's no longer the case, else nothing | 578 | // out: true if the linda was full but it's no longer the case, else false |
| 574 | int keepercall_set(lua_State* const L_) | 579 | int keepercall_set(lua_State* const L_) |
| 575 | { | 580 | { |
| 576 | KeeperState const _K{ L_ }; | 581 | KeeperState const _K{ L_ }; |
| @@ -593,7 +598,7 @@ int keepercall_set(lua_State* const L_) | |||
| 593 | lua_pushnil(_K); // _K: KeysDB key nil | 598 | lua_pushnil(_K); // _K: KeysDB key nil |
| 594 | lua_rawset(_K, -3); // _K: KeysDB | 599 | lua_rawset(_K, -3); // _K: KeysDB |
| 595 | } else { | 600 | } else { |
| 596 | lua_remove(_K, -2); // _K: KeysDB KeyUD | 601 | lua_remove(_K, -2); // KeyUD::reset expects KeyUD at the top // _K: KeysDB KeyUD |
| 597 | // we create room if the KeyUD was full but it is no longer the case | 602 | // we create room if the KeyUD was full but it is no longer the case |
| 598 | _should_wake_writers = _key->reset(_K); | 603 | _should_wake_writers = _key->reset(_K); |
| 599 | } | 604 | } |
| @@ -619,7 +624,9 @@ int keepercall_set(lua_State* const L_) | |||
| 619 | lua_replace(_K, -2 - _count); // _K: KeysDB KeyUD val... | 624 | lua_replace(_K, -2 - _count); // _K: KeysDB KeyUD val... |
| 620 | [[maybe_unused]] bool const _pushed{ _key->push(_K, _count) }; // _K: KeysDB | 625 | [[maybe_unused]] bool const _pushed{ _key->push(_K, _count) }; // _K: KeysDB |
| 621 | } | 626 | } |
| 622 | return _should_wake_writers ? (lua_pushboolean(_K, 1), 1) : 0; | 627 | // stack isn't the same here depending on what we did before, but that's not a problem |
| 628 | lua_pushboolean(_K, _should_wake_writers ? 1 : 0); // _K: ... bool | ||
| 629 | return 1; | ||
| 623 | } | 630 | } |
| 624 | 631 | ||
| 625 | // ################################################################################################# | 632 | // ################################################################################################# |
diff --git a/src/lanes.lua b/src/lanes.lua index d890adf..c860ba0 100644 --- a/src/lanes.lua +++ b/src/lanes.lua | |||
| @@ -400,7 +400,8 @@ local configure_timers = function() | |||
| 400 | 400 | ||
| 401 | -- Timer lane; initialize only on the first 'require "lanes"' instance (which naturally has 'table' always declared) | 401 | -- Timer lane; initialize only on the first 'require "lanes"' instance (which naturally has 'table' always declared) |
| 402 | local first_time_key = "first time" | 402 | local first_time_key = "first time" |
| 403 | local first_time = timerLinda:get(first_time_key) == nil | 403 | local _, _first_time_val = timerLinda:get(first_time_key) |
| 404 | local first_time = (_first_time_val == nil) | ||
| 404 | timerLinda:set(first_time_key, true) | 405 | timerLinda:set(first_time_key, true) |
| 405 | if first_time then | 406 | if first_time then |
| 406 | 407 | ||
| @@ -490,8 +491,8 @@ local configure_timers = function() | |||
| 490 | -- | 491 | -- |
| 491 | local t2 = t1[key_] | 492 | local t2 = t1[key_] |
| 492 | if not t2 then | 493 | if not t2 then |
| 493 | t2= {} | 494 | t2 = {} |
| 494 | t1[key_]= t2 | 495 | t1[key_] = t2 |
| 495 | end | 496 | end |
| 496 | 497 | ||
| 497 | t2[1] = wakeup_at_ | 498 | t2[1] = wakeup_at_ |
| @@ -507,10 +508,10 @@ local configure_timers = function() | |||
| 507 | local now = now_secs() | 508 | local now = now_secs() |
| 508 | local next_wakeup | 509 | local next_wakeup |
| 509 | 510 | ||
| 510 | for linda_deep,t1 in pairs(collection) do | 511 | for linda_deep, t1 in pairs(collection) do |
| 511 | for key,t2 in pairs(t1) do | 512 | for key, t2 in pairs(t1) do |
| 512 | -- | 513 | -- |
| 513 | if key==linda_deep then | 514 | if key == linda_deep then |
| 514 | -- no 'continue' in Lua :/ | 515 | -- no 'continue' in Lua :/ |
| 515 | else | 516 | else |
| 516 | -- 't2': { wakeup_at_secs [,period_secs] } | 517 | -- 't2': { wakeup_at_secs [,period_secs] } |
| @@ -519,10 +520,10 @@ local configure_timers = function() | |||
| 519 | local period= t2[2] -- may be 'nil' | 520 | local period= t2[2] -- may be 'nil' |
| 520 | 521 | ||
| 521 | if wakeup_at <= now then | 522 | if wakeup_at <= now then |
| 522 | local linda= t1[linda_deep] | 523 | local linda = t1[linda_deep] |
| 523 | assert(linda) | 524 | assert(linda) |
| 524 | 525 | ||
| 525 | linda:set(key, now ) | 526 | linda:set(key, now) |
| 526 | 527 | ||
| 527 | -- 'pairs()' allows the values to be modified (and even | 528 | -- 'pairs()' allows the values to be modified (and even |
| 528 | -- removed) as far as keys are not touched | 529 | -- removed) as far as keys are not touched |
| @@ -530,13 +531,13 @@ local configure_timers = function() | |||
| 530 | if not period then | 531 | if not period then |
| 531 | -- one-time timer; gone | 532 | -- one-time timer; gone |
| 532 | -- | 533 | -- |
| 533 | t1[key]= nil | 534 | t1[key] = nil |
| 534 | wakeup_at= nil -- no 'continue' in Lua :/ | 535 | wakeup_at = nil -- no 'continue' in Lua :/ |
| 535 | else | 536 | else |
| 536 | -- repeating timer; find next wakeup (may jump multiple repeats) | 537 | -- repeating timer; find next wakeup (may jump multiple repeats) |
| 537 | -- | 538 | -- |
| 538 | repeat | 539 | repeat |
| 539 | wakeup_at= wakeup_at+period | 540 | wakeup_at= wakeup_at+period |
| 540 | until wakeup_at > now | 541 | until wakeup_at > now |
| 541 | 542 | ||
| 542 | t2[1]= wakeup_at | 543 | t2[1]= wakeup_at |
| @@ -544,7 +545,7 @@ local configure_timers = function() | |||
| 544 | end | 545 | end |
| 545 | 546 | ||
| 546 | if wakeup_at and ((not next_wakeup) or (wakeup_at < next_wakeup)) then | 547 | if wakeup_at and ((not next_wakeup) or (wakeup_at < next_wakeup)) then |
| 547 | next_wakeup= wakeup_at | 548 | next_wakeup = wakeup_at |
| 548 | end | 549 | end |
| 549 | end | 550 | end |
| 550 | end -- t2 loop | 551 | end -- t2 loop |
| @@ -675,7 +676,12 @@ local cancel_error | |||
| 675 | local genlock = function(linda_, key_, N) | 676 | local genlock = function(linda_, key_, N) |
| 676 | -- clear existing data and set the limit | 677 | -- clear existing data and set the limit |
| 677 | N = N or 1 | 678 | N = N or 1 |
| 678 | if linda_:set(key_) == cancel_error or linda_:limit(key_, N) == cancel_error then | 679 | local _status, _err = linda_:set(key_) |
| 680 | if _err == cancel_error then | ||
| 681 | return cancel_error | ||
| 682 | end | ||
| 683 | local _status, _err = linda_:limit(key_, N) | ||
| 684 | if _err == cancel_error then | ||
| 679 | return cancel_error | 685 | return cancel_error |
| 680 | end | 686 | end |
| 681 | 687 | ||
| @@ -723,7 +729,12 @@ end -- genlock | |||
| 723 | -- | 729 | -- |
| 724 | local genatomic = function(linda_, key_, initial_val_) | 730 | local genatomic = function(linda_, key_, initial_val_) |
| 725 | -- clears existing data (also queue). the slot may contain the stored value, and an additional boolean value | 731 | -- clears existing data (also queue). the slot may contain the stored value, and an additional boolean value |
| 726 | if linda_:limit(key_, 2) == cancel_error or linda_:set(key_, initial_val_ or 0.0) == cancel_error then | 732 | local _status, _err = linda_:limit(key_, 2) |
| 733 | if _err == cancel_error then | ||
| 734 | return cancel_error | ||
| 735 | end | ||
| 736 | local _status, _err = linda_:set(key_, initial_val_ or 0.0) | ||
| 737 | if _err == cancel_error then | ||
| 727 | return cancel_error | 738 | return cancel_error |
| 728 | end | 739 | end |
| 729 | 740 | ||
| @@ -734,7 +745,7 @@ local genatomic = function(linda_, key_, initial_val_) | |||
| 734 | if _err == cancel_error then | 745 | if _err == cancel_error then |
| 735 | return cancel_error | 746 | return cancel_error |
| 736 | end | 747 | end |
| 737 | local val = linda_:get(key_) | 748 | local _, val = linda_:get(key_) |
| 738 | if val ~= cancel_error then | 749 | if val ~= cancel_error then |
| 739 | val = val + (diff_ or 1.0) | 750 | val = val + (diff_ or 1.0) |
| 740 | -- set() releases the lock by emptying queue | 751 | -- set() releases the lock by emptying queue |
diff --git a/src/linda.cpp b/src/linda.cpp index 91138c5..316e917 100644 --- a/src/linda.cpp +++ b/src/linda.cpp | |||
| @@ -393,7 +393,7 @@ LUAG_FUNC(linda_dump) | |||
| 393 | // ################################################################################################# | 393 | // ################################################################################################# |
| 394 | 394 | ||
| 395 | /* | 395 | /* |
| 396 | * [val [, ...]] = linda_get( linda_ud, key_num|str|bool|lightuserdata [, count = 1]) | 396 | * count, [val [, ...]]|nil,cancel_error = linda:get(key_num|str|bool|lightuserdata [, count = 1]) |
| 397 | * | 397 | * |
| 398 | * Get one or more values from Linda. | 398 | * Get one or more values from Linda. |
| 399 | */ | 399 | */ |
| @@ -412,9 +412,10 @@ LUAG_FUNC(linda_get) | |||
| 412 | Keeper* const _keeper{ _linda->whichKeeper() }; | 412 | Keeper* const _keeper{ _linda->whichKeeper() }; |
| 413 | _pushed = keeper_call(_keeper->K, KEEPER_API(get), L_, _linda, 2); | 413 | _pushed = keeper_call(_keeper->K, KEEPER_API(get), L_, _linda, 2); |
| 414 | } else { // linda is cancelled | 414 | } else { // linda is cancelled |
| 415 | // do nothing and return lanes.cancel_error | 415 | // do nothing and return nil,lanes.cancel_error |
| 416 | lua_pushnil(L_); | ||
| 416 | kCancelError.pushKey(L_); | 417 | kCancelError.pushKey(L_); |
| 417 | _pushed.emplace(1); | 418 | _pushed.emplace(2); |
| 418 | } | 419 | } |
| 419 | // an error can be raised if we attempt to read an unregistered function | 420 | // an error can be raised if we attempt to read an unregistered function |
| 420 | return OptionalValue(_pushed, L_, "tried to copy unsupported types"); | 421 | return OptionalValue(_pushed, L_, "tried to copy unsupported types"); |
| @@ -425,7 +426,7 @@ LUAG_FUNC(linda_get) | |||
| 425 | // ################################################################################################# | 426 | // ################################################################################################# |
| 426 | 427 | ||
| 427 | /* | 428 | /* |
| 428 | * [true] = linda_limit( linda_ud, key_num|str|bool|lightuserdata, [int]) | 429 | * [bool]|nil,cancel_error = linda:limit(key_num|str|bool|lightuserdata, [int]) |
| 429 | * | 430 | * |
| 430 | * Set limit to 1 Linda keys. | 431 | * Set limit to 1 Linda keys. |
| 431 | * Optionally wake threads waiting to write on the linda, in case the limit enables them to do so | 432 | * Optionally wake threads waiting to write on the linda, in case the limit enables them to do so |
| @@ -450,15 +451,15 @@ LUAG_FUNC(linda_limit) | |||
| 450 | if (_linda->cancelRequest == CancelRequest::None) { | 451 | if (_linda->cancelRequest == CancelRequest::None) { |
| 451 | Keeper* const _keeper{ _linda->whichKeeper() }; | 452 | Keeper* const _keeper{ _linda->whichKeeper() }; |
| 452 | _pushed = keeper_call(_keeper->K, KEEPER_API(limit), L_, _linda, 2); | 453 | _pushed = keeper_call(_keeper->K, KEEPER_API(limit), L_, _linda, 2); |
| 453 | LUA_ASSERT(L_, _pushed.has_value() && (_pushed.value() == 0 || _pushed.value() == 1)); // no error, optional boolean value saying if we should wake blocked writer threads | 454 | LUA_ASSERT(L_, _pushed.has_value() && (_pushed.value() == 1) && luaG_type(L_, -1) == LuaType::BOOLEAN); // no error, boolean value saying if we should wake blocked writer threads |
| 454 | if (_pushed.value() == 1) { | 455 | if (lua_toboolean(L_, -1)) { |
| 455 | LUA_ASSERT(L_, luaG_type(L_, -1) == LuaType::BOOLEAN && lua_toboolean(L_, -1) == 1); | ||
| 456 | _linda->readHappened.notify_all(); // To be done from within the 'K' locking area | 456 | _linda->readHappened.notify_all(); // To be done from within the 'K' locking area |
| 457 | } | 457 | } |
| 458 | } else { // linda is cancelled | 458 | } else { // linda is cancelled |
| 459 | // do nothing and return lanes.cancel_error | 459 | // do nothing and return nil,lanes.cancel_error |
| 460 | lua_pushnil(L_); | ||
| 460 | kCancelError.pushKey(L_); | 461 | kCancelError.pushKey(L_); |
| 461 | _pushed.emplace(1); | 462 | _pushed.emplace(2); |
| 462 | } | 463 | } |
| 463 | // propagate pushed boolean if any | 464 | // propagate pushed boolean if any |
| 464 | return _pushed.value(); | 465 | return _pushed.value(); |
| @@ -470,14 +471,13 @@ LUAG_FUNC(linda_limit) | |||
| 470 | 471 | ||
| 471 | /* | 472 | /* |
| 472 | * 2 modes of operation | 473 | * 2 modes of operation |
| 473 | * [val, key]= linda_receive( linda_ud, [timeout_secs_num=nil], key_num|str|bool|lightuserdata [, ...] ) | 474 | * [val, key]= linda:receive([timeout_secs_num=nil], key_num|str|bool|lightuserdata [, ...] ) |
| 474 | * Consumes a single value from the Linda, in any key. | 475 | * Consumes a single value from the Linda, in any key. |
| 475 | * Returns: received value (which is consumed from the slot), and the key which had it | 476 | * Returns: received value (which is consumed from the slot), and the key which had it |
| 476 | 477 | ||
| 477 | * [val1, ... valCOUNT]= linda_receive( linda_ud, [timeout_secs_num=-1], linda.batched, key_num|str|bool|lightuserdata, min_COUNT[, max_COUNT]) | 478 | * [val1, ... valCOUNT]= linda_receive( linda_ud, [timeout_secs_num=-1], linda.batched, key_num|str|bool|lightuserdata, min_COUNT[, max_COUNT]) |
| 478 | * Consumes between min_COUNT and max_COUNT values from the linda, from a single key. | 479 | * Consumes between min_COUNT and max_COUNT values from the linda, from a single key. |
| 479 | * returns the actual consumed values, or nil if there weren't enough values to consume | 480 | * returns the actual consumed values, or nil if there weren't enough values to consume |
| 480 | * | ||
| 481 | */ | 481 | */ |
| 482 | LUAG_FUNC(linda_receive) | 482 | LUAG_FUNC(linda_receive) |
| 483 | { | 483 | { |
| @@ -763,7 +763,7 @@ LUAG_FUNC(linda_send) | |||
| 763 | // ################################################################################################# | 763 | // ################################################################################################# |
| 764 | 764 | ||
| 765 | /* | 765 | /* |
| 766 | * [true|lanes.cancel_error] = linda_set( linda_ud, key_num|str|bool|lightuserdata [, value [, ...]]) | 766 | * [true|nil,lanes.cancel_error] = linda:set(key_num|str|bool|lightuserdata [, value [, ...]]) |
| 767 | * | 767 | * |
| 768 | * Set one or more value to Linda. Ignores limits. | 768 | * Set one or more value to Linda. Ignores limits. |
| 769 | * | 769 | * |
| @@ -773,7 +773,7 @@ LUAG_FUNC(linda_set) | |||
| 773 | { | 773 | { |
| 774 | auto set = [](lua_State* L_) { | 774 | auto set = [](lua_State* L_) { |
| 775 | Linda* const _linda{ ToLinda<false>(L_, 1) }; | 775 | Linda* const _linda{ ToLinda<false>(L_, 1) }; |
| 776 | bool const _has_value{ lua_gettop(L_) > 2 }; | 776 | bool const _has_data{ lua_gettop(L_) > 2 }; |
| 777 | // make sure the key is of a valid type (throws an error if not the case) | 777 | // make sure the key is of a valid type (throws an error if not the case) |
| 778 | check_key_types(L_, 2, 2); | 778 | check_key_types(L_, 2, 2); |
| 779 | 779 | ||
| @@ -782,22 +782,22 @@ LUAG_FUNC(linda_set) | |||
| 782 | if (_linda->cancelRequest == CancelRequest::None) { | 782 | if (_linda->cancelRequest == CancelRequest::None) { |
| 783 | _pushed = keeper_call(_keeper->K, KEEPER_API(set), L_, _linda, 2); | 783 | _pushed = keeper_call(_keeper->K, KEEPER_API(set), L_, _linda, 2); |
| 784 | if (_pushed.has_value()) { // no error? | 784 | if (_pushed.has_value()) { // no error? |
| 785 | LUA_ASSERT(L_, _pushed.value() == 0 || _pushed.value() == 1); | 785 | LUA_ASSERT(L_, _pushed.value() == 1 && luaG_type(L_, -1) == LuaType::BOOLEAN); |
| 786 | 786 | ||
| 787 | if (_has_value) { | 787 | if (_has_data) { |
| 788 | // we put some data in the slot, tell readers that they should wake | 788 | // we put some data in the slot, tell readers that they should wake |
| 789 | _linda->writeHappened.notify_all(); // To be done from within the 'K' locking area | 789 | _linda->writeHappened.notify_all(); // To be done from within the 'K' locking area |
| 790 | } | 790 | } |
| 791 | if (_pushed.value() == 1) { | 791 | if (lua_toboolean(L_, -1)) { |
| 792 | // the key was full, but it is no longer the case, tell writers they should wake | 792 | // the key was full, but it is no longer the case, tell writers they should wake |
| 793 | LUA_ASSERT(L_, luaG_type(L_, -1) == LuaType::BOOLEAN && lua_toboolean(L_, -1) == 1); | ||
| 794 | _linda->readHappened.notify_all(); // To be done from within the 'K' locking area | 793 | _linda->readHappened.notify_all(); // To be done from within the 'K' locking area |
| 795 | } | 794 | } |
| 796 | } | 795 | } |
| 797 | } else { // linda is cancelled | 796 | } else { // linda is cancelled |
| 798 | // do nothing and return lanes.cancel_error | 797 | // do nothing and return nil,lanes.cancel_error |
| 798 | lua_pushnil(L_); | ||
| 799 | kCancelError.pushKey(L_); | 799 | kCancelError.pushKey(L_); |
| 800 | _pushed.emplace(1); | 800 | _pushed.emplace(2); |
| 801 | } | 801 | } |
| 802 | 802 | ||
| 803 | // must trigger any error after keeper state has been released | 803 | // must trigger any error after keeper state has been released |
