aboutsummaryrefslogtreecommitdiff
path: root/src/lanes.lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/lanes.lua')
-rw-r--r--src/lanes.lua72
1 files changed, 32 insertions, 40 deletions
diff --git a/src/lanes.lua b/src/lanes.lua
index 01ca181..0e27ea6 100644
--- a/src/lanes.lua
+++ b/src/lanes.lua
@@ -35,13 +35,15 @@ THE SOFTWARE.
35=============================================================================== 35===============================================================================
36]]-- 36]]--
37 37
38local core = require "lanes.core"
38-- Lua 5.1: module() creates a global variable 39-- Lua 5.1: module() creates a global variable
39-- Lua 5.2: module() is gone 40-- Lua 5.2: module() is gone
40-- almost everything module() does is done by require() anyway 41-- almost everything module() does is done by require() anyway
41-- -> simply create a table, populate it, return it, and be done 42-- -> simply create a table, populate it, return it, and be done
42local lanes = {} 43local lanes = {}
43 44
44lanes.configure = function( _params) 45-- this function is available in the public interface until it is called, after which it disappears
46lanes.configure = function( settings_)
45 47
46 -- This check is for sublanes requiring Lanes 48 -- This check is for sublanes requiring Lanes
47 -- 49 --
@@ -68,7 +70,7 @@ lanes.configure = function( _params)
68 on_state_create = nil, 70 on_state_create = nil,
69 shutdown_timeout = 0.25, 71 shutdown_timeout = 0.25,
70 with_timers = true, 72 with_timers = true,
71 track_lanes = nil, 73 track_lanes = false,
72 verbose_errors = false, 74 verbose_errors = false,
73 -- LuaJIT provides a thread-unsafe allocator by default, so we need to protect it when used in parallel lanes 75 -- LuaJIT provides a thread-unsafe allocator by default, so we need to protect it when used in parallel lanes
74 protect_allocator = (jit and jit.version) and true or false 76 protect_allocator = (jit and jit.version) and true or false
@@ -117,35 +119,32 @@ lanes.configure = function( _params)
117 end 119 end
118 } 120 }
119 121
120 local params_checker = function( _params) 122 local params_checker = function( settings_)
121 if not _params then 123 if not settings_ then
122 return default_params 124 return default_params
123 end 125 end
124 if type( _params) ~= "table" then 126 -- make a copy of the table to leave the provided one unchanged, *and* to help ensure it won't change behind our back
125 error( "Bad parameter #1 to lanes.configure(), should be a table") 127 local settings = {}
128 if type( settings_) ~= "table" then
129 error "Bad parameter #1 to lanes.configure(), should be a table"
126 end 130 end
127 -- any setting not present in the provided parameters takes the default value 131 -- any setting not present in the provided parameters takes the default value
128 for key, value in pairs( default_params) do 132 for key, checker in pairs( param_checkers) do
129 local my_param = _params[key] 133 local my_param = settings_[key]
130 local param 134 local param
131 if my_param ~= nil then 135 if my_param ~= nil then
132 param = my_param 136 param = my_param
133 else 137 else
134 param = default_params[key] 138 param = default_params[key]
135 end 139 end
136 if not param_checkers[key]( param) then 140 if not checker( param) then
137 error( "Bad " .. key .. ": " .. tostring( param), 2) 141 error( "Bad " .. key .. ": " .. tostring( param), 2)
138 end 142 end
139 _params[key] = param 143 settings[key] = param
140 end 144 end
141 return _params 145 return settings
142 end 146 end
143 147 local settings = core.configure and core.configure( params_checker( settings_)) or core.settings
144 _params = params_checker( _params)
145
146 local core = require "lanes.core"
147 assert( type( core)=="table")
148 core.configure( _params.nb_keepers, _params.on_state_create, _params.shutdown_timeout, _params.track_lanes, _params.protect_allocator, _params.verbose_errors)
149 local thread_new = assert( core.thread_new) 148 local thread_new = assert( core.thread_new)
150 local set_singlethreaded = assert( core.set_singlethreaded) 149 local set_singlethreaded = assert( core.set_singlethreaded)
151 local max_prio = assert( core.max_prio) 150 local max_prio = assert( core.max_prio)
@@ -316,8 +315,8 @@ local function gen( ... )
316 -- Lane generator 315 -- Lane generator
317 -- 316 --
318 return function(...) 317 return function(...)
319 return thread_new( func, libs, _params.on_state_create, cs, prio, g_tbl, package_tbl, required, ...) -- args 318 return thread_new( func, libs, settings.on_state_create, cs, prio, g_tbl, package_tbl, required, ...) -- args
320 end 319 end
321end 320end
322 321
323---=== Lindas ===--- 322---=== Lindas ===---
@@ -338,7 +337,7 @@ local timer = function() error "timers are not active" end
338local timer_lane = nil 337local timer_lane = nil
339local timers = timer 338local timers = timer
340 339
341if _params.with_timers ~= false then 340if settings.with_timers ~= false then
342 341
343local timer_gateway = assert( core.timer_gateway) 342local timer_gateway = assert( core.timer_gateway)
344-- 343--
@@ -364,6 +363,8 @@ timer_gateway:set(first_time_key,true)
364-- 363--
365if first_time then 364if first_time then
366 365
366 local now_secs = core.now_secs
367 assert( type( now_secs) == "function")
367 ----- 368 -----
368 -- Snore loop (run as a lane on the background) 369 -- Snore loop (run as a lane on the background)
369 -- 370 --
@@ -373,10 +374,7 @@ if first_time then
373 -- remains. 374 -- remains.
374 -- 375 --
375 local timer_body = function() 376 local timer_body = function()
376 -- require lanes.core inside the timer body to prevent pulling now_secs() through an uvpvalue 377 set_debug_threadname( "LanesTimer")
377 local core = require "lanes.core"
378 core.configure( _params.nb_keepers, _params.on_state_create, _params.shutdown_timeout, _params.track_lanes, _params.protect_allocator, _params.verbose_errors)
379
380 -- 378 --
381 -- { [deep_linda_lightuserdata]= { [deep_linda_lightuserdata]=linda_h, 379 -- { [deep_linda_lightuserdata]= { [deep_linda_lightuserdata]=linda_h,
382 -- [key]= { wakeup_secs [,period_secs] } [, ...] }, 380 -- [key]= { wakeup_secs [,period_secs] } [, ...] },
@@ -463,8 +461,6 @@ if first_time then
463 end 461 end
464 end -- set_timer() 462 end -- set_timer()
465 463
466 local now_secs = core.now_secs
467 assert( type( now_secs) == "function")
468 ----- 464 -----
469 -- [next_wakeup_at]= check_timers() 465 -- [next_wakeup_at]= check_timers()
470 -- Check timers, and wake up the ones expired (if any) 466 -- Check timers, and wake up the ones expired (if any)
@@ -520,7 +516,6 @@ if first_time then
520 end -- check_timers() 516 end -- check_timers()
521 517
522 local timer_gateway_batched = timer_gateway.batched 518 local timer_gateway_batched = timer_gateway.batched
523 set_debug_threadname( "LanesTimer")
524 set_finalizer( function( err, stk) 519 set_finalizer( function( err, stk)
525 if err and type( err) ~= "userdata" then 520 if err and type( err) ~= "userdata" then
526 WR( "LanesTimer error: "..tostring(err)) 521 WR( "LanesTimer error: "..tostring(err))
@@ -601,7 +596,7 @@ timers = function()
601 return r 596 return r
602end 597end
603 598
604end -- _params.with_timers 599end -- settings.with_timers
605 600
606---=== Lock & atomic generators ===--- 601---=== Lock & atomic generators ===---
607 602
@@ -673,26 +668,23 @@ end
673 lanes.linda = core.linda 668 lanes.linda = core.linda
674 lanes.cancel_error = core.cancel_error 669 lanes.cancel_error = core.cancel_error
675 lanes.nameof = core.nameof 670 lanes.nameof = core.nameof
676 lanes.threads = (_params.track_lanes and core.threads) and core.threads or function() error "lane tracking is not available" end 671 lanes.threads = core.threads or function() error "lane tracking is not available" end -- core.threads isn't registered if settings.track_lanes is false
677 lanes.timer = timer 672 lanes.timer = timer
678 lanes.timer_lane = timer_lane 673 lanes.timer_lane = timer_lane
679 lanes.timers = timers 674 lanes.timers = timers
680 lanes.genlock = genlock 675 lanes.genlock = genlock
681 lanes.now_secs = core.now_secs 676 lanes.now_secs = core.now_secs
682 lanes.genatomic = genatomic 677 lanes.genatomic = genatomic
683 -- from now on, calling configure does nothing but checking that we don't call it with parameters that changed compared to the first invocation 678 lanes.configure = nil -- no need to call configure() ever again
684 lanes.configure = function( _params2)
685 _params2 = params_checker( _params2 or _params)
686 for key, value2 in pairs( _params2) do
687 local value = _params[key]
688 if value2 ~= value then
689 error( "mismatched configuration: " .. key .. " is " .. tostring( value2) .. " instead of " .. tostring( value))
690 end
691 end
692 return lanes
693 end
694 return lanes 679 return lanes
695end -- lanes.configure 680end -- lanes.configure
696 681
682-- no need to force calling configure() excepted the first time
683if core.settings then
684 return lanes.configure()
685else
686 return lanes
687end
688
697--the end 689--the end
698return lanes 690return lanes