aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lanes.cpp4
-rw-r--r--src/lanes.lua97
2 files changed, 59 insertions, 42 deletions
diff --git a/src/lanes.cpp b/src/lanes.cpp
index a5e4236..473e150 100644
--- a/src/lanes.cpp
+++ b/src/lanes.cpp
@@ -242,6 +242,7 @@ LUAG_FUNC(register)
242// , [gc_cb_func] 242// , [gc_cb_func]
243// , [name] 243// , [name]
244// , error_trace_level 244// , error_trace_level
245// , as_coroutine
245// [, ... args ...]) 246// [, ... args ...])
246// 247//
247// Upvalues: metatable to use for 'lane_ud' 248// Upvalues: metatable to use for 'lane_ud'
@@ -257,7 +258,8 @@ LUAG_FUNC(lane_new)
257 static constexpr int kGcCbIdx{ 7 }; 258 static constexpr int kGcCbIdx{ 7 };
258 static constexpr int kNameIdx{ 8 }; 259 static constexpr int kNameIdx{ 8 };
259 static constexpr int kErTlIdx{ 9 }; 260 static constexpr int kErTlIdx{ 9 };
260 static constexpr int kFixedArgsIdx{ 9 }; 261 static constexpr int kAsCoro{ 10 };
262 static constexpr int kFixedArgsIdx{ 10 };
261 263
262 int const _nargs{ lua_gettop(L_) - kFixedArgsIdx }; 264 int const _nargs{ lua_gettop(L_) - kFixedArgsIdx };
263 LUA_ASSERT(L_, _nargs >= 0); 265 LUA_ASSERT(L_, _nargs >= 0);
diff --git a/src/lanes.lua b/src/lanes.lua
index d28fcf4..57183e9 100644
--- a/src/lanes.lua
+++ b/src/lanes.lua
@@ -284,46 +284,7 @@ local opt_validators =
284-- ##################################### lanes.gen() ########################################### 284-- ##################################### lanes.gen() ###########################################
285-- ############################################################################################# 285-- #############################################################################################
286 286
287-- lane_h[1..n]: lane results, same as via 'lane_h:join()' 287local process_gen_opt = function(...)
288-- lane_h[0]: can be read to make sure a thread has finished (always gives 'true')
289-- lane_h[-1]: error message, without propagating the error
290--
291-- Reading a Lane result (or [0]) propagates a possible error in the lane
292-- (and execution does not return). Cancelled lanes give 'nil' values.
293--
294-- lane_h.state: "pending"/"running"/"waiting"/"done"/"error"/"cancelled"
295--
296-- Note: Would be great to be able to have '__ipairs' metamethod, that gets
297-- called by 'ipairs()' function to custom iterate objects. We'd use it
298-- for making sure a lane has ended (results are available); not requiring
299-- the user to precede a loop by explicit 'h[0]' or 'h:join()'.
300--
301-- Or, even better, 'ipairs()' should start valuing '__index' instead
302-- of using raw reads that bypass it.
303--
304-----
305-- lanes.gen([libs_str|opt_tbl [, ...],] lane_func ) ([...]) -> h
306--
307-- 'libs': nil: no libraries available (default)
308-- "": only base library ('assert', 'print', 'unpack' etc.)
309-- "math,os": math + os + base libraries (named ones + base)
310-- "*": all standard libraries available
311--
312-- 'opt': .priority: int (-3..+3) smaller is lower priority (0 = default)
313--
314-- .globals: table of globals to set for a new thread (passed by value)
315--
316-- .required: table of packages to require
317--
318-- .gc_cb: function called when the lane handle is collected
319--
320-- ... (more options may be introduced later) ...
321--
322-- Calling with a function argument ('lane_func') ends the string/table
323-- modifiers, and prepares a lane generator.
324
325-- receives a sequence of strings and tables, plus a function
326local gen = function(...)
327 -- aggregrate all strings together, separated by "," as well as tables 288 -- aggregrate all strings together, separated by "," as well as tables
328 -- the strings are a list of libraries to open 289 -- the strings are a list of libraries to open
329 -- the tables contain the lane options 290 -- the tables contain the lane options
@@ -392,15 +353,68 @@ local gen = function(...)
392 opt[k] = validator(v) 353 opt[k] = validator(v)
393 end 354 end
394 end 355 end
356 return func, libs, opt
357end -- process_gen_opt
358
359-- lane_h[1..n]: lane results, same as via 'lane_h:join()'
360-- lane_h[0]: can be read to make sure a thread has finished (always gives 'true')
361-- lane_h[-1]: error message, without propagating the error
362--
363-- Reading a Lane result (or [0]) propagates a possible error in the lane
364-- (and execution does not return). Cancelled lanes give 'nil' values.
365--
366-- lane_h.state: "pending"/"running"/"waiting"/"done"/"error"/"cancelled"
367--
368-- Note: Would be great to be able to have '__ipairs' metamethod, that gets
369-- called by 'ipairs()' function to custom iterate objects. We'd use it
370-- for making sure a lane has ended (results are available); not requiring
371-- the user to precede a loop by explicit 'h[0]' or 'h:join()'.
372--
373-- Or, even better, 'ipairs()' should start valuing '__index' instead
374-- of using raw reads that bypass it.
375--
376-----
377-- lanes.gen([libs_str|opt_tbl [, ...],] lane_func ) ([...]) -> h
378--
379-- 'libs': nil: no libraries available (default)
380-- "": only base library ('assert', 'print', 'unpack' etc.)
381-- "math,os": math + os + base libraries (named ones + base)
382-- "*": all standard libraries available
383--
384-- 'opt': .priority: int (-3..+3) smaller is lower priority (0 = default)
385--
386-- .globals: table of globals to set for a new thread (passed by value)
387--
388-- .required: table of packages to require
389--
390-- .gc_cb: function called when the lane handle is collected
391--
392-- ... (more options may be introduced later) ...
393--
394-- Calling with a function argument ('lane_func') ends the string/table
395-- modifiers, and prepares a lane generator.
395 396
397-- receives a sequence of strings and tables, plus a function
398local gen = function(...)
399 local func, libs, opt = process_gen_opt(...)
396 local core_lane_new = assert(core.lane_new) 400 local core_lane_new = assert(core.lane_new)
397 local priority, globals, package, required, gc_cb, name, error_trace_level = opt.priority, opt.globals, opt.package or package, opt.required, opt.gc_cb, opt.name, error_trace_levels[opt.error_trace_level] 401 local priority, globals, package, required, gc_cb, name, error_trace_level = opt.priority, opt.globals, opt.package or package, opt.required, opt.gc_cb, opt.name, error_trace_levels[opt.error_trace_level]
398 return function(...) 402 return function(...)
399 -- must pass functions args last else they will be truncated to the first one 403 -- must pass functions args last else they will be truncated to the first one
400 return core_lane_new(func, libs, priority, globals, package, required, gc_cb, name, error_trace_level, ...) 404 return core_lane_new(func, libs, priority, globals, package, required, gc_cb, name, error_trace_level, false, ...)
401 end 405 end
402end -- gen() 406end -- gen()
403 407
408local coro = function(...)
409 local func, libs, opt = process_gen_opt(...)
410 local core_lane_new = assert(core.lane_new)
411 local priority, globals, package, required, gc_cb, name, error_trace_level = opt.priority, opt.globals, opt.package or package, opt.required, opt.gc_cb, opt.name, error_trace_levels[opt.error_trace_level]
412 return function(...)
413 -- must pass functions args last else they will be truncated to the first one
414 return core_lane_new(func, libs, priority, globals, package, required, gc_cb, name, error_trace_level, true, ...)
415 end
416end -- coro()
417
404-- ################################################################################################# 418-- #################################################################################################
405-- ####################################### Timers ################################################## 419-- ####################################### Timers ##################################################
406-- ################################################################################################# 420-- #################################################################################################
@@ -850,6 +864,7 @@ local configure = function(settings_)
850 lanes.threads = core.threads or function() error "lane tracking is not available" end -- core.threads isn't registered if settings.track_lanes is false 864 lanes.threads = core.threads or function() error "lane tracking is not available" end -- core.threads isn't registered if settings.track_lanes is false
851 865
852 lanes.gen = gen 866 lanes.gen = gen
867 lanes.coro = coro
853 lanes.genatomic = genatomic 868 lanes.genatomic = genatomic
854 lanes.genlock = genlock 869 lanes.genlock = genlock
855 lanes.timer = timer 870 lanes.timer = timer