diff options
Diffstat (limited to 'src/lanes.lua')
-rw-r--r-- | src/lanes.lua | 72 |
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 | ||
38 | local 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 |
42 | local lanes = {} | 43 | local lanes = {} |
43 | 44 | ||
44 | lanes.configure = function( _params) | 45 | -- this function is available in the public interface until it is called, after which it disappears |
46 | lanes.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 |
321 | end | 320 | end |
322 | 321 | ||
323 | ---=== Lindas ===--- | 322 | ---=== Lindas ===--- |
@@ -338,7 +337,7 @@ local timer = function() error "timers are not active" end | |||
338 | local timer_lane = nil | 337 | local timer_lane = nil |
339 | local timers = timer | 338 | local timers = timer |
340 | 339 | ||
341 | if _params.with_timers ~= false then | 340 | if settings.with_timers ~= false then |
342 | 341 | ||
343 | local timer_gateway = assert( core.timer_gateway) | 342 | local timer_gateway = assert( core.timer_gateway) |
344 | -- | 343 | -- |
@@ -364,6 +363,8 @@ timer_gateway:set(first_time_key,true) | |||
364 | -- | 363 | -- |
365 | if first_time then | 364 | if 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 |
602 | end | 597 | end |
603 | 598 | ||
604 | end -- _params.with_timers | 599 | end -- 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 |
695 | end -- lanes.configure | 680 | end -- lanes.configure |
696 | 681 | ||
682 | -- no need to force calling configure() excepted the first time | ||
683 | if core.settings then | ||
684 | return lanes.configure() | ||
685 | else | ||
686 | return lanes | ||
687 | end | ||
688 | |||
697 | --the end | 689 | --the end |
698 | return lanes | 690 | return lanes |