aboutsummaryrefslogtreecommitdiff
path: root/src/lanes.lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/lanes.lua')
-rw-r--r--src/lanes.lua142
1 files changed, 87 insertions, 55 deletions
diff --git a/src/lanes.lua b/src/lanes.lua
index e6400df..c9ab07d 100644
--- a/src/lanes.lua
+++ b/src/lanes.lua
@@ -40,55 +40,93 @@ THE SOFTWARE.
40]]-- 40]]--
41 41
42-- Lua 5.1: module() creates a global variable 42-- Lua 5.1: module() creates a global variable
43-- Lua 5.2: module() might go away 43-- Lua 5.2: module() is gone
44-- almost everything module() does is done by require() 44-- almost everything module() does is done by require() anyway
45-- -> simply create a table, populate it, return it, and be done 45-- -> simply create a table, populate it, return it, and be done
46local lanes = {} 46local lanes = {}
47 47
48lanes.configure = function( _params) 48lanes.configure = function( _params)
49_params = _params or { nb_keepers = 1, with_timers = true, on_state_create = nil}
50if type( _params) ~= "table" then
51 error( "Bad parameter #1 to lanes.configure(), should be a table")
52end
53-- on_state_create may be nil or a function
54if _params.on_state_create and (type( _params.on_state_create) ~= "function") then
55 error( "Bad on_state_create: " .. tostring( _params.on_state_create), 2)
56end
57 49
58local mm = require "lanes.core" 50 -- This check is for sublanes requiring Lanes
59assert( type(mm)=="table" ) 51 --
52 -- TBD: We could also have the C level expose 'string.gmatch' for us. But this is simpler.
53 --
54 if not string then
55 error( "To use 'lanes', you will also need to have 'string' available.", 2)
56 end
60 57
61-- configure() is available only the first time lanes.core is required process-wide, and we *must* call it to have the other functions in the interface 58 --
62if mm.configure then mm.configure( _params.nb_keepers, _params.on_state_create) end 59 -- Cache globals for code that might run under sandboxing
60 --
61 local assert = assert
62 local string_gmatch = assert( string.gmatch)
63 local select = assert( select)
64 local type = assert( type)
65 local pairs = assert( pairs)
66 local tostring = assert( tostring)
67 local error = assert( error)
68
69 local default_params = { nb_keepers = 1, on_state_create = nil, shutdown_timeout = 0.25, with_timers = true}
70 local param_checkers =
71 {
72 nb_keepers = function( _val)
73 -- nb_keepers should be a number > 0
74 return type( _val) == "number" and _val > 0
75 end,
76 with_timers = function( _val)
77 -- with_timers may be nil or boolean
78 return _val and type( _val) == "boolean" or true
79 end,
80 on_state_create = function( _val)
81 -- on_state_create may be nil or a function
82 return _val and type( _val) == "function" or true
83 end,
84 shutdown_timeout = function( _val)
85 -- nb_keepers should be a number >= 0
86 return type( _val) == "number" and _val >= 0
87 end
88 }
63 89
64local thread_new = assert(mm.thread_new) 90 local params_checker = function( _params)
91 if not _params then
92 return default_params
93 end
94 if type( _params) ~= "table" then
95 error( "Bad parameter #1 to lanes.configure(), should be a table")
96 end
97 -- any setting not present in the provided parameters takes the default value
98 for key, value in pairs( default_params) do
99 local my_param = _params[key]
100 local param
101 if my_param ~= nil then
102 param = my_param
103 else
104 param = default_params[key]
105 end
106 if not param_checkers[key]( param) then
107 error( "Bad " .. key .. ": " .. tostring( param), 2)
108 end
109 _params[key] = param
110 end
111 return _params
112 end
65 113
66local _single= assert(mm._single) 114 _params = params_checker( _params)
67local _version= assert(mm._version)
68 115
69local now_secs= assert( mm.now_secs ) 116 local core = require "lanes.core"
70local wakeup_conv= assert( mm.wakeup_conv ) 117 assert( type( core)=="table")
71 118
72local max_prio= assert( mm.max_prio ) 119 -- configure() is available only the first time lanes.core is required process-wide, and we *must* call it to have the other functions in the interface
120 if core.configure then core.configure( _params.nb_keepers, _params.on_state_create, _params.shutdown_timeout) end
73 121
74-- This check is for sublanes requiring Lanes 122 local thread_new = assert( core.thread_new)
75--
76-- TBD: We could also have the C level expose 'string.gmatch' for us. But this is simpler.
77--
78if not string then
79 error( "To use 'lanes', you will also need to have 'string' available.", 2 )
80end
81 123
82-- 124 local set_singlethreaded = assert( core.set_singlethreaded)
83-- Cache globals for code that might run under sandboxing 125
84-- 126 local now_secs = assert( core.now_secs)
85local assert= assert 127 local wakeup_conv = assert( core.wakeup_conv)
86local string_gmatch= assert( string.gmatch ) 128
87local select= assert( select ) 129 local max_prio = assert( core.max_prio)
88local type= assert( type )
89local pairs= assert( pairs )
90local tostring= assert( tostring )
91local error= assert( error )
92 130
93lanes.ABOUT= 131lanes.ABOUT=
94{ 132{
@@ -96,7 +134,7 @@ lanes.ABOUT=
96 description= "Running multiple Lua states in parallel", 134 description= "Running multiple Lua states in parallel",
97 license= "MIT/X11", 135 license= "MIT/X11",
98 copyright= "Copyright (c) 2007-10, Asko Kauppi; (c) 2011-12, Benoit Germain", 136 copyright= "Copyright (c) 2007-10, Asko Kauppi; (c) 2011-12, Benoit Germain",
99 version= _version, 137 version = assert( core.version)
100} 138}
101 139
102 140
@@ -258,7 +296,7 @@ end
258-- lanes.linda(["name"]) -> linda_ud 296-- lanes.linda(["name"]) -> linda_ud
259-- 297--
260-- PUBLIC LANES API 298-- PUBLIC LANES API
261local linda = mm.linda 299local linda = core.linda
262 300
263 301
264---=== Timers ===--- 302---=== Timers ===---
@@ -268,7 +306,7 @@ local timer = function() error "timers are not active" end
268 306
269if _params.with_timers ~= false then 307if _params.with_timers ~= false then
270 308
271local timer_gateway= assert( mm.timer_gateway ) 309local timer_gateway = assert( core.timer_gateway)
272-- 310--
273-- On first 'require "lanes"', a timer lane is spawned that will maintain 311-- On first 'require "lanes"', a timer lane is spawned that will maintain
274-- timer tables and sleep in between the timer events. All interaction with 312-- timer tables and sleep in between the timer events. All interaction with
@@ -558,28 +596,23 @@ local function genatomic( linda, key, initial_val )
558 end 596 end
559end 597end
560 598
561-- newuserdata = mm.newuserdata
562
563 -- activate full interface 599 -- activate full interface
564 lanes.gen = gen 600 lanes.gen = gen
565 lanes.linda = mm.linda 601 lanes.linda = core.linda
566 lanes.cancel_error = mm.cancel_error 602 lanes.cancel_error = core.cancel_error
567 lanes.nameof = mm.nameof 603 lanes.nameof = core.nameof
568 lanes.timer = timer 604 lanes.timer = timer
569 lanes.genlock = genlock 605 lanes.genlock = genlock
570 lanes.now_secs = now_secs 606 lanes.now_secs = now_secs
571 lanes.genatomic = genatomic 607 lanes.genatomic = genatomic
572 -- from now on, calling configure does nothing but checking that we don't call it with parameters that changed compared to the first invocation 608 -- from now on, calling configure does nothing but checking that we don't call it with parameters that changed compared to the first invocation
573 lanes.configure = function( _params2) 609 lanes.configure = function( _params2)
574 _params2 = _params2 or _params 610 _params2 = params_checker( _params2 or _params)
575 if _params2.nb_keepers ~= _params.nb_keepers then 611 for key, value2 in pairs( _params2) do
576 error( "mismatched configuration: " .. tostring( _params2.nb_keepers) .. " keepers instead of " .. tostring( _params.nb_keepers)) 612 local value = _params[key]
577 end 613 if value2 ~= value then
578 if _params2.with_timers ~= _params.with_timers then 614 error( "mismatched configuration: " .. key .. " is " .. tostring( value2) .. " instead of " .. tostring( value))
579 error( "mismatched configuration: " .. tostring( _params2.with_timers) .. " timer activity instead of " .. tostring( _params.with_timers)) 615 end
580 end
581 if _params2.on_create_state and _params2.on_create_state ~= _params.on_create_state then
582 error( "mismatched configuration: " .. tostring( _params2.on_create_state) .. " timer activity instead of " .. tostring( _params.on_create_state))
583 end 616 end
584 return lanes 617 return lanes
585 end 618 end
@@ -588,4 +621,3 @@ end -- lanes.configure
588 621
589--the end 622--the end
590return lanes 623return lanes
591