diff options
author | Benoit Germain <bnt.germain@gmail.com> | 2012-02-18 14:08:52 +0100 |
---|---|---|
committer | Benoit Germain <bnt.germain@gmail.com> | 2012-02-18 14:08:52 +0100 |
commit | 076344633e7b2525cf48005f84f3935f324b60bf (patch) | |
tree | 2a013da0ba2cd4a9f7eaf073a5ba128723f13154 /src/lanes.c | |
parent | b4582dd0bb65a916de7fa9612880b75a17c7ae7f (diff) | |
download | lanes-076344633e7b2525cf48005f84f3935f324b60bf.tar.gz lanes-076344633e7b2525cf48005f84f3935f324b60bf.tar.bz2 lanes-076344633e7b2525cf48005f84f3935f324b60bf.zip |
* changed lanes.configure signature to receive a table instead of individual parameters
* added support for an on_state_create callback called to load custom functions in a state in addition to the base libraries
Diffstat (limited to 'src/lanes.c')
-rw-r--r-- | src/lanes.c | 66 |
1 files changed, 30 insertions, 36 deletions
diff --git a/src/lanes.c b/src/lanes.c index 676032a..513a006 100644 --- a/src/lanes.c +++ b/src/lanes.c | |||
@@ -51,7 +51,7 @@ | |||
51 | * ... | 51 | * ... |
52 | */ | 52 | */ |
53 | 53 | ||
54 | const char *VERSION= "3.0-beta"; | 54 | char const* VERSION = "3.1.0"; |
55 | 55 | ||
56 | /* | 56 | /* |
57 | =============================================================================== | 57 | =============================================================================== |
@@ -1540,7 +1540,7 @@ static void require_one_module( lua_State *L, lua_State *L2, bool_t _fatal) | |||
1540 | { | 1540 | { |
1541 | lua_pop( L2, 1); | 1541 | lua_pop( L2, 1); |
1542 | if( _fatal) | 1542 | if( _fatal) |
1543 | luaL_error( L, "cannot pre-require modules without loading package library first"); | 1543 | luaL_error( L, "cannot pre-require modules without loading 'package' library first"); |
1544 | } | 1544 | } |
1545 | else | 1545 | else |
1546 | { | 1546 | { |
@@ -1557,14 +1557,15 @@ LUAG_FUNC( thread_new ) | |||
1557 | struct s_lane *s; | 1557 | struct s_lane *s; |
1558 | struct s_lane **ud; | 1558 | struct s_lane **ud; |
1559 | 1559 | ||
1560 | const char *libs= lua_tostring( L, 2 ); | 1560 | char const* libs = lua_tostring( L, 2); |
1561 | uint_t cs= luaG_optunsigned( L, 3,0); | 1561 | lua_CFunction on_state_create = lua_iscfunction( L, 3) ? lua_tocfunction( L, 3) : NULL; |
1562 | int prio= (int)luaL_optinteger( L, 4,0); | 1562 | uint_t cs = luaG_optunsigned( L, 4, 0); |
1563 | uint_t glob= luaG_isany(L,5) ? 5:0; | 1563 | int prio = (int) luaL_optinteger( L, 5, 0); |
1564 | uint_t package = luaG_isany(L,6) ? 6:0; | 1564 | uint_t glob = luaG_isany( L, 6) ? 6 : 0; |
1565 | uint_t required = luaG_isany(L,7) ? 7:0; | 1565 | uint_t package = luaG_isany( L,7) ? 7 : 0; |
1566 | uint_t required = luaG_isany( L, 8) ? 8 : 0; | ||
1566 | 1567 | ||
1567 | #define FIXED_ARGS (7) | 1568 | #define FIXED_ARGS 8 |
1568 | uint_t args= lua_gettop(L) - FIXED_ARGS; | 1569 | uint_t args= lua_gettop(L) - FIXED_ARGS; |
1569 | 1570 | ||
1570 | if (prio < THREAD_PRIO_MIN || prio > THREAD_PRIO_MAX) | 1571 | if (prio < THREAD_PRIO_MIN || prio > THREAD_PRIO_MAX) |
@@ -1575,23 +1576,13 @@ LUAG_FUNC( thread_new ) | |||
1575 | 1576 | ||
1576 | /* --- Create and prepare the sub state --- */ | 1577 | /* --- Create and prepare the sub state --- */ |
1577 | 1578 | ||
1578 | L2 = luaL_newstate(); // uses standard 'realloc()'-based allocator, | 1579 | // populate with selected libraries at the same time |
1579 | // sets the panic callback | 1580 | // |
1580 | 1581 | L2 = luaG_newstate( libs, on_state_create); | |
1581 | if (!L2) luaL_error( L, "'luaL_newstate()' failed; out of memory" ); | 1582 | if (!L2) luaL_error( L, "'luaL_newstate()' failed; out of memory" ); |
1582 | 1583 | ||
1583 | STACK_GROW( L, 2); | 1584 | STACK_GROW( L, 2); |
1584 | 1585 | ||
1585 | // Selected libraries | ||
1586 | // | ||
1587 | if (libs) | ||
1588 | { | ||
1589 | const char *err= luaG_openlibs( L2, libs); | ||
1590 | ASSERT_L( !err ); // bad libs should have been noticed by 'lanes.lua' | ||
1591 | |||
1592 | serialize_require( L2); | ||
1593 | } | ||
1594 | |||
1595 | ASSERT_L( lua_gettop(L2) == 0); | 1586 | ASSERT_L( lua_gettop(L2) == 0); |
1596 | 1587 | ||
1597 | // package.path | 1588 | // package.path |
@@ -1600,7 +1591,7 @@ LUAG_FUNC( thread_new ) | |||
1600 | if( package) | 1591 | if( package) |
1601 | { | 1592 | { |
1602 | if (lua_type(L,package) != LUA_TTABLE) | 1593 | if (lua_type(L,package) != LUA_TTABLE) |
1603 | luaL_error( L, "expected package as table, got %s", luaG_typename(L,package)); | 1594 | luaL_error( L, "expected package as table, got %s", luaL_typename(L,package)); |
1604 | lua_getglobal( L2, "package"); | 1595 | lua_getglobal( L2, "package"); |
1605 | if( !lua_isnil( L2, -1)) // package library not loaded: do nothing | 1596 | if( !lua_isnil( L2, -1)) // package library not loaded: do nothing |
1606 | { | 1597 | { |
@@ -1628,7 +1619,7 @@ LUAG_FUNC( thread_new ) | |||
1628 | // modules to require in the target lane *before* the function is transfered! | 1619 | // modules to require in the target lane *before* the function is transfered! |
1629 | 1620 | ||
1630 | //start by requiring lua51-lanes, since it is a bit special | 1621 | //start by requiring lua51-lanes, since it is a bit special |
1631 | // it not fatal if 'require' isn't loaded, just ignore (may cause function transfer errors later on if the lane pulls the lanes module itself) | 1622 | // it is not fatal if 'require' isn't loaded, just ignore (may cause function transfer errors later on if the lane pulls the lanes module itself) |
1632 | STACK_CHECK(L) | 1623 | STACK_CHECK(L) |
1633 | STACK_CHECK(L2) | 1624 | STACK_CHECK(L2) |
1634 | lua_pushliteral( L, "lua51-lanes"); | 1625 | lua_pushliteral( L, "lua51-lanes"); |
@@ -1644,7 +1635,7 @@ LUAG_FUNC( thread_new ) | |||
1644 | int nbRequired = 1; | 1635 | int nbRequired = 1; |
1645 | // should not happen, was checked in lanes.lua before calling thread_new() | 1636 | // should not happen, was checked in lanes.lua before calling thread_new() |
1646 | if (lua_type(L, required) != LUA_TTABLE) | 1637 | if (lua_type(L, required) != LUA_TTABLE) |
1647 | luaL_error( L, "expected required module list as a table, got %s", luaG_typename( L, required)); | 1638 | luaL_error( L, "expected required module list as a table, got %s", luaL_typename( L, required)); |
1648 | lua_pushnil( L); | 1639 | lua_pushnil( L); |
1649 | while( lua_next( L, required) != 0) | 1640 | while( lua_next( L, required) != 0) |
1650 | { | 1641 | { |
@@ -1671,7 +1662,7 @@ LUAG_FUNC( thread_new ) | |||
1671 | STACK_CHECK(L) | 1662 | STACK_CHECK(L) |
1672 | STACK_CHECK(L2) | 1663 | STACK_CHECK(L2) |
1673 | if (!lua_istable(L,glob)) | 1664 | if (!lua_istable(L,glob)) |
1674 | luaL_error( L, "Expected table, got %s", luaG_typename(L,glob)); | 1665 | luaL_error( L, "Expected table, got %s", luaL_typename(L,glob)); |
1675 | 1666 | ||
1676 | lua_pushnil( L); | 1667 | lua_pushnil( L); |
1677 | while( lua_next( L, glob)) | 1668 | while( lua_next( L, glob)) |
@@ -2240,7 +2231,7 @@ static const struct luaL_reg lanes_functions [] = { | |||
2240 | /* | 2231 | /* |
2241 | * One-time initializations | 2232 | * One-time initializations |
2242 | */ | 2233 | */ |
2243 | static void init_once_LOCKED( lua_State *L, volatile DEEP_PRELUDE ** timer_deep_ref, int const nbKeepers) | 2234 | static void init_once_LOCKED( lua_State* L, volatile DEEP_PRELUDE** timer_deep_ref, int const nbKeepers, lua_CFunction _on_state_create) |
2244 | { | 2235 | { |
2245 | const char *err; | 2236 | const char *err; |
2246 | 2237 | ||
@@ -2291,7 +2282,7 @@ static void init_once_LOCKED( lua_State *L, volatile DEEP_PRELUDE ** timer_deep_ | |||
2291 | } | 2282 | } |
2292 | #endif | 2283 | #endif |
2293 | #endif | 2284 | #endif |
2294 | err= init_keepers( nbKeepers); | 2285 | err = init_keepers( nbKeepers, _on_state_create); |
2295 | if (err) | 2286 | if (err) |
2296 | { | 2287 | { |
2297 | luaL_error( L, "Unable to initialize: %s", err ); | 2288 | luaL_error( L, "Unable to initialize: %s", err ); |
@@ -2338,9 +2329,11 @@ static volatile long s_initCount = 0; | |||
2338 | 2329 | ||
2339 | LUAG_FUNC( configure ) | 2330 | LUAG_FUNC( configure ) |
2340 | { | 2331 | { |
2341 | char const *name = luaL_checkstring( L, lua_upvalueindex( 1)); | 2332 | char const* name = luaL_checkstring( L, lua_upvalueindex( 1)); |
2342 | int const nbKeepers = luaL_optint( L, 1, 1); | 2333 | int const nbKeepers = luaL_optint( L, 1, 1); |
2343 | luaL_argcheck( L, nbKeepers > 0, 2, "Number of keeper states must be > 0"); | 2334 | lua_CFunction on_state_create = lua_iscfunction( L, 2) ? lua_tocfunction( L, 2) : NULL; |
2335 | luaL_argcheck( L, nbKeepers > 0, 1, "Number of keeper states must be > 0"); | ||
2336 | luaL_argcheck( L, lua_iscfunction( L, 2) || lua_isnil( L, 2), 2, "on_state_create should be a C function"); | ||
2344 | /* | 2337 | /* |
2345 | * Making one-time initializations. | 2338 | * Making one-time initializations. |
2346 | * | 2339 | * |
@@ -2353,7 +2346,7 @@ LUAG_FUNC( configure ) | |||
2353 | static volatile int /*bool*/ go_ahead; // = 0 | 2346 | static volatile int /*bool*/ go_ahead; // = 0 |
2354 | if( InterlockedCompareExchange( &s_initCount, 1, 0) == 0) | 2347 | if( InterlockedCompareExchange( &s_initCount, 1, 0) == 0) |
2355 | { | 2348 | { |
2356 | init_once_LOCKED(L, &timer_deep, nbKeepers); | 2349 | init_once_LOCKED( L, &timer_deep, nbKeepers, on_state_create); |
2357 | go_ahead= 1; // let others pass | 2350 | go_ahead= 1; // let others pass |
2358 | } | 2351 | } |
2359 | else | 2352 | else |
@@ -2365,13 +2358,13 @@ LUAG_FUNC( configure ) | |||
2365 | if( s_initCount == 0) | 2358 | if( s_initCount == 0) |
2366 | { | 2359 | { |
2367 | static pthread_mutex_t my_lock= PTHREAD_MUTEX_INITIALIZER; | 2360 | static pthread_mutex_t my_lock= PTHREAD_MUTEX_INITIALIZER; |
2368 | pthread_mutex_lock(&my_lock); | 2361 | pthread_mutex_lock( &my_lock); |
2369 | { | 2362 | { |
2370 | // Recheck now that we're within the lock | 2363 | // Recheck now that we're within the lock |
2371 | // | 2364 | // |
2372 | if (s_initCount == 0) | 2365 | if( s_initCount == 0) |
2373 | { | 2366 | { |
2374 | init_once_LOCKED(L, &timer_deep, nbKeepers); | 2367 | init_once_LOCKED( L, &timer_deep, nbKeepers, on_state_create); |
2375 | s_initCount = 1; | 2368 | s_initCount = 1; |
2376 | } | 2369 | } |
2377 | } | 2370 | } |
@@ -2451,10 +2444,11 @@ luaopen_lanes( lua_State *L ) | |||
2451 | { | 2444 | { |
2452 | lua_setfield( L, -2, "configure"); | 2445 | lua_setfield( L, -2, "configure"); |
2453 | } | 2446 | } |
2454 | else // already initialized: call it mmediately and be done | 2447 | else // already initialized: call it immediately and be done |
2455 | { | 2448 | { |
2456 | lua_pushinteger( L, 666); // any value will do, it will be ignored | 2449 | lua_pushinteger( L, 666); // any value will do, it will be ignored |
2457 | lua_call( L, 1, 0); | 2450 | lua_pushnil( L); // almost idem |
2451 | lua_call( L, 2, 0); | ||
2458 | } | 2452 | } |
2459 | STACK_END( L, 1) | 2453 | STACK_END( L, 1) |
2460 | return 1; | 2454 | return 1; |