aboutsummaryrefslogtreecommitdiff
path: root/src/lanes.c
diff options
context:
space:
mode:
authorBenoit Germain <bnt.germain@gmail.com>2012-02-18 14:08:52 +0100
committerBenoit Germain <bnt.germain@gmail.com>2012-02-18 14:08:52 +0100
commit076344633e7b2525cf48005f84f3935f324b60bf (patch)
tree2a013da0ba2cd4a9f7eaf073a5ba128723f13154 /src/lanes.c
parentb4582dd0bb65a916de7fa9612880b75a17c7ae7f (diff)
downloadlanes-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.c66
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
54const char *VERSION= "3.0-beta"; 54char 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*/
2243static void init_once_LOCKED( lua_State *L, volatile DEEP_PRELUDE ** timer_deep_ref, int const nbKeepers) 2234static 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
2339LUAG_FUNC( configure ) 2330LUAG_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;