summaryrefslogtreecommitdiff
path: root/src/keeper.c
diff options
context:
space:
mode:
authorBenoit Germain <bnt.germain@gmail.com>2013-01-24 22:46:21 +0100
committerBenoit Germain <bnt.germain@gmail.com>2013-01-24 22:46:21 +0100
commit68d8db431ec2b739dc53233d6b4d8aeee9324e48 (patch)
treed8f0fbe0f8c4e1a07ac4248fd1b7673f49beb4d3 /src/keeper.c
parent623fb3c0cae9beb3d5e7d3f7424b47d80041c1ac (diff)
downloadlanes-3.4.3.tar.gz
lanes-3.4.3.tar.bz2
lanes-3.4.3.zip
version 3.4.3v3.4.3
* raise an error if lane generator libs specification contains a lib more than once * bit32 is a valid lib name in the libs specification (silently ignored by the Lua 5.1 build) * improved lanes.nameof to search inside table- and userdata- metatables for an object's name * fixed an unwarranted error when trying to discover a function name upon a failed transfer * contents of package.[path,cpath,preload,loaders|searchers] are pulled *only once* inside keeper states at initialisation * Lua function upvalues equal to the global environment aren't copied by value, but bound to the destination's global environment especially useful for Lua 5.2 _ENV * fixed loading of base libraries that didn't create the global tables when built for Lua 5.2
Diffstat (limited to '')
-rw-r--r--src/keeper.c57
1 files changed, 23 insertions, 34 deletions
diff --git a/src/keeper.c b/src/keeper.c
index 0be4fd3..a7c8647 100644
--- a/src/keeper.c
+++ b/src/keeper.c
@@ -557,7 +557,7 @@ void close_keepers( void)
557* unclosed, because it does not really matter. In production code, this 557* unclosed, because it does not really matter. In production code, this
558* function never fails. 558* function never fails.
559*/ 559*/
560char const* init_keepers( int const _nbKeepers, lua_CFunction _on_state_create) 560char const* init_keepers( lua_State* L, int const _nbKeepers, lua_CFunction _on_state_create)
561{ 561{
562 int i; 562 int i;
563 assert( _nbKeepers >= 1); 563 assert( _nbKeepers >= 1);
@@ -565,15 +565,16 @@ char const* init_keepers( int const _nbKeepers, lua_CFunction _on_state_create)
565 GKeepers = malloc( _nbKeepers * sizeof( struct s_Keeper)); 565 GKeepers = malloc( _nbKeepers * sizeof( struct s_Keeper));
566 for( i = 0; i < _nbKeepers; ++ i) 566 for( i = 0; i < _nbKeepers; ++ i)
567 { 567 {
568
569 // We need to load all base libraries in the keeper states so that the transfer databases are populated properly 568 // We need to load all base libraries in the keeper states so that the transfer databases are populated properly
570 // 569 //
571 // 'io' for debugging messages, 'package' because we need to require modules exporting idfuncs 570 // 'io' for debugging messages, 'package' because we need to require modules exporting idfuncs
572 // the others because they export functions that we may store in a keeper for transfer between lanes 571 // the others because they export functions that we may store in a keeper for transfer between lanes
573 lua_State* K = luaG_newstate( "*", _on_state_create); 572 lua_State* K = luaG_newstate( "*", _on_state_create);
574 if (!K) 573 if( !K)
575 return "out of memory"; 574 return "out of memory";
576 575
576 DEBUGSPEW_CODE( fprintf( stderr, "init_keepers %d\n", i));
577
577 STACK_CHECK( K) 578 STACK_CHECK( K)
578 // to see VM name in Decoda debugger 579 // to see VM name in Decoda debugger
579 lua_pushliteral( K, "Keeper #"); 580 lua_pushliteral( K, "Keeper #");
@@ -581,6 +582,11 @@ char const* init_keepers( int const _nbKeepers, lua_CFunction _on_state_create)
581 lua_concat( K, 2); 582 lua_concat( K, 2);
582 lua_setglobal( K, "decoda_name"); 583 lua_setglobal( K, "decoda_name");
583 584
585 // replace default 'package' contents with stuff gotten from the master state
586 lua_getglobal( L, "package");
587 luaG_inter_copy_package( L, K, -1);
588 lua_pop( L, 1);
589
584#if KEEPER_MODEL == KEEPER_MODEL_C 590#if KEEPER_MODEL == KEEPER_MODEL_C
585 // create the fifos table in the keeper state 591 // create the fifos table in the keeper state
586 lua_pushlightuserdata( K, fifos_key); 592 lua_pushlightuserdata( K, fifos_key);
@@ -589,7 +595,7 @@ char const* init_keepers( int const _nbKeepers, lua_CFunction _on_state_create)
589#endif // KEEPER_MODEL == KEEPER_MODEL_C 595#endif // KEEPER_MODEL == KEEPER_MODEL_C
590 596
591#if KEEPER_MODEL == KEEPER_MODEL_LUA 597#if KEEPER_MODEL == KEEPER_MODEL_LUA
592 // use package.loaders[2] to find keeper microcode 598 // use package.loaders[2] to find keeper microcode (NOTE: this works only if nobody tampered with the loaders table...)
593 lua_getglobal( K, "package"); // package 599 lua_getglobal( K, "package"); // package
594 lua_getfield( K, -1, "loaders"); // package package.loaders 600 lua_getfield( K, -1, "loaders"); // package package.loaders
595 lua_rawgeti( K, -1, 2); // package package.loaders package.loaders[2] 601 lua_rawgeti( K, -1, 2); // package package.loaders package.loaders[2]
@@ -619,55 +625,38 @@ char const* init_keepers( int const _nbKeepers, lua_CFunction _on_state_create)
619} 625}
620 626
621// cause each keeper state to populate its database of transferable functions with those from the specified module 627// cause each keeper state to populate its database of transferable functions with those from the specified module
622void populate_keepers( lua_State *L) 628// do do this we simply require the module inside the keeper state, then populate the lookup database
629void populate_keepers( lua_State* L)
623{ 630{
624 size_t name_len; 631 size_t name_len;
625 char const *name = luaL_checklstring( L, -1, &name_len); 632 char const* name = luaL_checklstring( L, -1, &name_len);
626 size_t package_path_len;
627 char const *package_path;
628 size_t package_cpath_len;
629 char const *package_cpath;
630 int i; 633 int i;
631 634
632 // we need to make sure that package.path & package.cpath are the same in the keepers 635 STACK_CHECK( L)
633// than what is currently in use when the module is required in the caller's Lua state
634 STACK_CHECK(L)
635 STACK_GROW( L, 3); 636 STACK_GROW( L, 3);
636 lua_getglobal( L, "package");
637 lua_getfield( L, -1, "path");
638 package_path = luaL_checklstring( L, -1, &package_path_len);
639 lua_getfield( L, -2, "cpath");
640 package_cpath = luaL_checklstring( L, -1, &package_cpath_len);
641 637
642 for( i = 0; i < GNbKeepers; ++ i) 638 for( i = 0; i < GNbKeepers; ++ i)
643 { 639 {
644 lua_State *K = GKeepers[i].L; 640 lua_State* K = GKeepers[i].L;
645 int res; 641 int res;
646 MUTEX_LOCK( &GKeepers[i].lock_); 642 MUTEX_LOCK( &GKeepers[i].lock_);
647 STACK_CHECK(K) 643 STACK_CHECK( K)
648 STACK_GROW( K, 2); 644 STACK_GROW( K, 2);
649 lua_getglobal( K, "package");
650 lua_pushlstring( K, package_path, package_path_len);
651 lua_setfield( K, -2, "path");
652 lua_pushlstring( K, package_cpath, package_cpath_len);
653 lua_setfield( K, -2, "cpath");
654 lua_pop( K, 1);
655 lua_getglobal( K, "require"); 645 lua_getglobal( K, "require");
656 lua_pushlstring( K, name, name_len); 646 lua_pushlstring( K, name, name_len);
657 res = lua_pcall( K, 1, 0, 0); 647 res = lua_pcall( K, 1, 0, 0);
658 if( res != 0) 648 if( res != 0)
659 { 649 {
660 char const *err = luaL_checkstring( K, -1); 650 char const* err = luaL_checkstring( K, -1);
661 luaL_error( L, "error requiring '%s' in keeper state: %s", name, err); 651 luaL_error( L, "error requiring '%s' in keeper state: %s", name, err);
662 } 652 }
663 STACK_END(K, 0) 653 STACK_END( K, 0)
664 MUTEX_UNLOCK( &GKeepers[i].lock_); 654 MUTEX_UNLOCK( &GKeepers[i].lock_);
665 } 655 }
666 lua_pop( L, 3); 656 STACK_END( L, 0)
667 STACK_END(L, 0)
668} 657}
669 658
670struct s_Keeper *keeper_acquire( const void *ptr) 659struct s_Keeper* keeper_acquire( void const* ptr)
671{ 660{
672 // can be 0 if this happens during main state shutdown (lanes is being GC'ed -> no keepers) 661 // can be 0 if this happens during main state shutdown (lanes is being GC'ed -> no keepers)
673 if( GNbKeepers == 0) 662 if( GNbKeepers == 0)
@@ -691,19 +680,19 @@ struct s_Keeper *keeper_acquire( const void *ptr)
691 } 680 }
692} 681}
693 682
694void keeper_release( struct s_Keeper *K) 683void keeper_release( struct s_Keeper* K)
695{ 684{
696 //-- K->count; 685 //-- K->count;
697 if( K) MUTEX_UNLOCK( &K->lock_); 686 if( K) MUTEX_UNLOCK( &K->lock_);
698} 687}
699 688
700void keeper_toggle_nil_sentinels( lua_State *L, int _val_i, int _nil_to_sentinel) 689void keeper_toggle_nil_sentinels( lua_State* L, int _val_i, int _nil_to_sentinel)
701{ 690{
702 int i, n = lua_gettop( L); 691 int i, n = lua_gettop( L);
703 /* We could use an empty table in 'keeper.lua' as the sentinel, but maybe 692 /* We could use an empty table in 'keeper.lua' as the sentinel, but maybe
704 * checking for a lightuserdata is faster. (any unique value will do -> take the address of some global of ours) 693 * checking for a lightuserdata is faster. (any unique value will do -> take the address of some global of ours)
705 */ 694 */
706 void *nil_sentinel = &GNbKeepers; 695 void* nil_sentinel = &GNbKeepers;
707 for( i = _val_i; i <= n; ++ i) 696 for( i = _val_i; i <= n; ++ i)
708 { 697 {
709 if( _nil_to_sentinel) 698 if( _nil_to_sentinel)