aboutsummaryrefslogtreecommitdiff
path: root/src/lanes.lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/lanes.lua')
-rw-r--r--src/lanes.lua88
1 files changed, 53 insertions, 35 deletions
diff --git a/src/lanes.lua b/src/lanes.lua
index 1286099..86dbe47 100644
--- a/src/lanes.lua
+++ b/src/lanes.lua
@@ -585,13 +585,25 @@ end
585 585
586end -- settings.with_timers 586end -- settings.with_timers
587 587
588-- avoid pulling the whole core module as upvalue when cancel_error is enough
589local cancel_error = assert( core.cancel_error)
590
588---=== Lock & atomic generators ===--- 591---=== Lock & atomic generators ===---
589 592
590-- These functions are just surface sugar, but make solutions easier to read. 593-- These functions are just surface sugar, but make solutions easier to read.
591-- Not many applications should even need explicit locks or atomic counters. 594-- Not many applications should even need explicit locks or atomic counters.
592 595
593-- 596--
594-- lock_f= lanes.genlock( linda_h, key [,N_uint=1] ) 597-- [true [, ...]= trues(uint)
598--
599local function trues( n)
600 if n > 0 then
601 return true, trues( n - 1)
602 end
603end
604
605--
606-- lock_f = lanes.genlock( linda_h, key [,N_uint=1] )
595-- 607--
596-- = lock_f( +M ) -- acquire M 608-- = lock_f( +M ) -- acquire M
597-- ...locked... 609-- ...locked...
@@ -602,16 +614,10 @@ end -- settings.with_timers
602-- 614--
603-- PUBLIC LANES API 615-- PUBLIC LANES API
604local genlock = function( linda, key, N) 616local genlock = function( linda, key, N)
605 linda:set( key) -- clears existing data 617 -- clear existing data and set the limit
606 linda:limit( key, N) 618 N = N or 1
607 619 if linda:set( key) == cancel_error or linda:limit( key, N) == cancel_error then
608 -- 620 return cancel_error
609 -- [true [, ...]= trues(uint)
610 --
611 local function trues( n)
612 if n > 0 then
613 return true, trues( n - 1)
614 end
615 end 621 end
616 622
617 -- use an optimized version for case N == 1 623 -- use an optimized version for case N == 1
@@ -623,7 +629,8 @@ local genlock = function( linda, key, N)
623 return linda:send( timeout, key, true) -- suspends until been able to push them 629 return linda:send( timeout, key, true) -- suspends until been able to push them
624 else 630 else
625 local k = linda:receive( nil, key) 631 local k = linda:receive( nil, key)
626 return k and true or false 632 -- propagate cancel_error if we got it, else return true or false
633 return k and ((k ~= cancel_error) and true or k) or false
627 end 634 end
628 end 635 end
629 or 636 or
@@ -634,34 +641,45 @@ local genlock = function( linda, key, N)
634 return linda:send( timeout, key, trues(M)) -- suspends until been able to push them 641 return linda:send( timeout, key, trues(M)) -- suspends until been able to push them
635 else 642 else
636 local k = linda:receive( nil, linda.batched, key, -M) 643 local k = linda:receive( nil, linda.batched, key, -M)
637 return k and true or false 644 -- propagate cancel_error if we got it, else return true or false
645 return k and ((k ~= cancel_error) and true or k) or false
638 end 646 end
639 end 647 end
640end 648end
641 649
642 650
643-- 651 --
644-- atomic_f= lanes.genatomic( linda_h, key [,initial_num=0.0] ) 652 -- atomic_f = lanes.genatomic( linda_h, key [,initial_num=0.0])
645-- 653 --
646-- int= atomic_f( [diff_num=1.0] ) 654 -- int|cancel_error = atomic_f( [diff_num = 1.0])
647-- 655 --
648-- Returns an access function that allows atomic increment/decrement of the 656 -- Returns an access function that allows atomic increment/decrement of the
649-- number in 'key'. 657 -- number in 'key'.
650-- 658 --
651-- PUBLIC LANES API 659 -- PUBLIC LANES API
652local function genatomic( linda, key, initial_val ) 660 local genatomic = function( linda, key, initial_val)
653 linda:limit(key,2) -- value [,true] 661 -- clears existing data (also queue). the slot may contain the stored value, and an additional boolean value
654 linda:set(key,initial_val or 0.0) -- clears existing data (also queue) 662 if linda:limit( key, 2) == cancel_error or linda:set( key, initial_val or 0.0) == cancel_error then
655 663 return cancel_error
656 return 664 end
657 function(diff) 665
658 -- 'nil' allows 'key' to be numeric 666 return function( diff)
659 linda:send( nil, key, true ) -- suspends until our 'true' is in 667 -- 'nil' allows 'key' to be numeric
660 local val= linda:get(key) + (diff or 1.0) 668 -- suspends until our 'true' is in
661 linda:set( key, val ) -- releases the lock, by emptying queue 669 if linda:send( nil, key, true) == cancel_error then
662 return val 670 return cancel_error
663 end 671 end
664end 672 local val = linda:get( key)
673 if val ~= cancel_error then
674 val = val + (diff or 1.0)
675 -- set() releases the lock by emptying queue
676 if linda:set( key, val) == cancel_error then
677 val = cancel_error
678 end
679 end
680 return val
681 end
682 end
665 683
666 -- activate full interface 684 -- activate full interface
667 lanes.require = core.require 685 lanes.require = core.require