From 4ece73b1e0d8f75fa63a5b39a91731147870bd0a Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Fri, 20 Dec 2013 11:46:42 +0100 Subject: new config option demote_full_userdata use demote_full_userdata to select between light userdata demotion or raising an error when attempting to transfer a non-deep full userdata --- src/lanes.lua | 50 ++++++++++++++++---------------------------------- src/tools.c | 25 ++++++++++++++++++++++--- 2 files changed, 38 insertions(+), 37 deletions(-) diff --git a/src/lanes.lua b/src/lanes.lua index 6e2a736..4856a2d 100644 --- a/src/lanes.lua +++ b/src/lanes.lua @@ -71,52 +71,34 @@ lanes.configure = function( settings_) shutdown_timeout = 0.25, with_timers = true, track_lanes = false, + demote_full_userdata = nil, verbose_errors = false, -- LuaJIT provides a thread-unsafe allocator by default, so we need to protect it when used in parallel lanes protect_allocator = (jit and jit.version) and true or false } + local boolean_param_checker = function( val_) + -- non-'boolean-false' should be 'boolean-true' or nil + return val_ and (val_ == true) or true + end local param_checkers = { - nb_keepers = function( _val) + nb_keepers = function( val_) -- nb_keepers should be a number > 0 - return type( _val) == "number" and _val > 0 - end, - with_timers = function( _val) - -- with_timers may be nil or boolean - if _val then - return type( _val) == "boolean" - else - return true -- _val is either false or nil - end + return type( val_) == "number" and val_ > 0 end, - protect_allocator = function( _val) - -- protect_allocator may be nil or boolean - if _val then - return type( _val) == "boolean" - else - return true -- _val is either false or nil - end - end, - on_state_create = function( _val) + with_timers = boolean_param_checker, + protect_allocator = boolean_param_checker, + on_state_create = function( val_) -- on_state_create may be nil or a function - return _val and type( _val) == "function" or true + return val_ and type( val_) == "function" or true end, - shutdown_timeout = function( _val) + shutdown_timeout = function( val_) -- shutdown_timeout should be a number >= 0 - return type( _val) == "number" and _val >= 0 - end, - track_lanes = function( _val) - -- track_lanes may be nil or boolean - return _val and type( _val) == "boolean" or true + return type( val_) == "number" and val_ >= 0 end, - verbose_errors = function( _val) - -- verbose_errors may be nil or boolean - if _val then - return type( _val) == "boolean" - else - return true -- _val is either false or nil - end - end + track_lanes = boolean_param_checker, + demote_full_userdata = boolean_param_checker, + verbose_errors = boolean_param_checker } local params_checker = function( settings_) diff --git a/src/tools.c b/src/tools.c index b5f2f4b..e743393 100644 --- a/src/tools.c +++ b/src/tools.c @@ -1886,9 +1886,28 @@ static bool_t inter_copy_one_( lua_State* L2, uint_t L2_cache_i, lua_State* L, u DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "USERDATA\n" INDENT_END)); if( !luaG_copydeep( L, L2, i)) { - // Cannot copy it full; copy as light userdata - // - lua_pushlightuserdata( L2, lua_touserdata( L, i)); + // Not a deep full userdata + bool_t demote = FALSE; + lua_getfield( L, LUA_REGISTRYINDEX, CONFIG_REGKEY); + if( lua_istable( L, -1)) // should not happen, but who knows... + { + lua_getfield( L, -1, "demote_full_userdata"); + demote = lua_toboolean( L, -1); + lua_pop( L, 2); + } + else + { + lua_pop( L, 1); + } + if( demote) // attempt demotion to light userdata + { + void* lud = lua_touserdata( L, i); + lua_pushlightuserdata( L2, lud); + } + else // raise an error + { + (void) luaL_error( L, "can't copy non-deep full userdata across lanes"); + } } break; -- cgit v1.2.3-55-g6feb