aboutsummaryrefslogtreecommitdiff
path: root/src/lanes.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lanes.c')
-rw-r--r--src/lanes.c120
1 files changed, 53 insertions, 67 deletions
diff --git a/src/lanes.c b/src/lanes.c
index dc1eeed..f4427a4 100644
--- a/src/lanes.c
+++ b/src/lanes.c
@@ -52,7 +52,7 @@
52 * ... 52 * ...
53 */ 53 */
54 54
55char const* VERSION = "3.6.5"; 55char const* VERSION = "3.6.6";
56 56
57/* 57/*
58=============================================================================== 58===============================================================================
@@ -414,8 +414,8 @@ LUAG_FUNC( linda_send)
414 414
415 STACK_GROW(L, 1); 415 STACK_GROW(L, 1);
416 { 416 {
417 struct s_Keeper *K = keeper_acquire( linda); 417 struct s_Keeper* K = keeper_acquire( linda);
418 lua_State *KL = K->L; // need to do this for 'STACK_CHECK' 418 lua_State* KL = K->L; // need to do this for 'STACK_CHECK'
419 STACK_CHECK( KL); 419 STACK_CHECK( KL);
420 for( ;;) 420 for( ;;)
421 { 421 {
@@ -2734,7 +2734,6 @@ LUAG_FUNC( configure)
2734 char const* name = luaL_checkstring( L, lua_upvalueindex( 1)); 2734 char const* name = luaL_checkstring( L, lua_upvalueindex( 1));
2735 // all parameter checks are done lua-side 2735 // all parameter checks are done lua-side
2736 int const nbKeepers = (int)lua_tointeger( L, 1); 2736 int const nbKeepers = (int)lua_tointeger( L, 1);
2737 // all these can be nil when lanes.core is required internally! (but are only processed at first init anyway)
2738 int const on_state_create = lua_isfunction( L, 2) ? 2 : 0; 2737 int const on_state_create = lua_isfunction( L, 2) ? 2 : 0;
2739 lua_Number shutdown_timeout = lua_tonumber( L, 3); 2738 lua_Number shutdown_timeout = lua_tonumber( L, 3);
2740 bool_t track_lanes = lua_toboolean( L, 4); 2739 bool_t track_lanes = lua_toboolean( L, 4);
@@ -2759,6 +2758,45 @@ LUAG_FUNC( configure)
2759 lua_setallocf( L, protected_lua_Alloc, s); 2758 lua_setallocf( L, protected_lua_Alloc, s);
2760 } 2759 }
2761 } 2760 }
2761 STACK_MID( L, 0);
2762
2763 /*
2764 ** Making one-time initializations.
2765 **
2766 ** When the host application is single-threaded (and all threading happens via Lanes)
2767 ** there is no problem. But if the host is multithreaded, we need to lock around the
2768 ** initializations.
2769 */
2770#if THREADAPI == THREADAPI_WINDOWS
2771 {
2772 static volatile int /*bool*/ go_ahead; // = 0
2773 if( InterlockedCompareExchange( &s_initCount, 1, 0) == 0)
2774 {
2775 init_once_LOCKED( L, on_state_create, nbKeepers, shutdown_timeout, track_lanes, verbose_errors);
2776 go_ahead = 1; // let others pass
2777 }
2778 else
2779 {
2780 while( !go_ahead) { Sleep(1); } // changes threads
2781 }
2782 }
2783#else // THREADAPI == THREADAPI_PTHREAD
2784 if( s_initCount == 0)
2785 {
2786 static pthread_mutex_t my_lock = PTHREAD_MUTEX_INITIALIZER;
2787 pthread_mutex_lock( &my_lock);
2788 {
2789 // Recheck now that we're within the lock
2790 //
2791 if( s_initCount == 0)
2792 {
2793 init_once_LOCKED( L, on_state_create, nbKeepers, shutdown_timeout, track_lanes, verbose_errors);
2794 s_initCount = 1;
2795 }
2796 }
2797 pthread_mutex_unlock( &my_lock);
2798 }
2799#endif // THREADAPI == THREADAPI_PTHREAD
2762 2800
2763 // Create main module interface table 2801 // Create main module interface table
2764 lua_pushvalue( L, lua_upvalueindex( 2)); // ... M 2802 lua_pushvalue( L, lua_upvalueindex( 2)); // ... M
@@ -2818,49 +2856,7 @@ LUAG_FUNC( configure)
2818 populate_func_lookup_table( L, -1, NULL); 2856 populate_func_lookup_table( L, -1, NULL);
2819 lua_pop( L, 1); // ... M 2857 lua_pop( L, 1); // ... M
2820 2858
2821 STACK_MID( L, 1); 2859 ASSERT_L( timer_deep != NULL);
2822 /*
2823 ** Making one-time initializations.
2824 **
2825 ** When the host application is single-threaded (and all threading happens via Lanes)
2826 ** there is no problem. But if the host is multithreaded, we need to lock around the
2827 ** initializations.
2828 ** we must do this after the populate_func_lookup_table is called, else populating the keepers will fail
2829 ** because this makes a copy of packages.loaders, which requires the lookup tables to exist!
2830 */
2831#if THREADAPI == THREADAPI_WINDOWS
2832 {
2833 static volatile int /*bool*/ go_ahead; // = 0
2834 if( InterlockedCompareExchange( &s_initCount, 1, 0) == 0)
2835 {
2836 init_once_LOCKED( L, on_state_create, nbKeepers, shutdown_timeout, track_lanes, verbose_errors);
2837 go_ahead = 1; // let others pass
2838 }
2839 else
2840 {
2841 while( !go_ahead ) { Sleep(1); } // changes threads
2842 }
2843 }
2844#else // THREADAPI == THREADAPI_PTHREAD
2845 if( s_initCount == 0)
2846 {
2847 static pthread_mutex_t my_lock = PTHREAD_MUTEX_INITIALIZER;
2848 pthread_mutex_lock( &my_lock);
2849 {
2850 // Recheck now that we're within the lock
2851 //
2852 if( s_initCount == 0)
2853 {
2854 init_once_LOCKED( L, on_state_create, nbKeepers, shutdown_timeout, track_lanes, verbose_errors);
2855 s_initCount = 1;
2856 }
2857 }
2858 pthread_mutex_unlock( &my_lock);
2859 }
2860#endif // THREADAPI == THREADAPI_PTHREAD
2861 STACK_MID( L, 1);
2862
2863 assert( timer_deep != NULL);
2864 // init_once_LOCKED initializes timer_deep, so we must do this after, of course 2860 // init_once_LOCKED initializes timer_deep, so we must do this after, of course
2865 luaG_push_proxy( L, linda_id, (DEEP_PRELUDE*) timer_deep); // ... M timer_deep 2861 luaG_push_proxy( L, linda_id, (DEEP_PRELUDE*) timer_deep); // ... M timer_deep
2866 lua_setfield( L, -2, "timer_gateway"); // ... M 2862 lua_setfield( L, -2, "timer_gateway"); // ... M
@@ -2875,9 +2871,9 @@ LUAG_FUNC( configure)
2875 2871
2876// helper to have correct callstacks when crashing a Win32 running on 64 bits Windows 2872// helper to have correct callstacks when crashing a Win32 running on 64 bits Windows
2877// don't forget to toggle Debug/Exceptions/Win32 in visual Studio too! 2873// don't forget to toggle Debug/Exceptions/Win32 in visual Studio too!
2878void EnableCrashingOnCrashes() 2874static void EnableCrashingOnCrashes( void)
2879{ 2875{
2880#if 0 && defined PLATFORM_WIN32 2876#if defined PLATFORM_WIN32 && !defined NDEBUG
2881 typedef BOOL (WINAPI *tGetPolicy)(LPDWORD lpFlags); 2877 typedef BOOL (WINAPI *tGetPolicy)(LPDWORD lpFlags);
2882 typedef BOOL (WINAPI *tSetPolicy)(DWORD dwFlags); 2878 typedef BOOL (WINAPI *tSetPolicy)(DWORD dwFlags);
2883 const DWORD EXCEPTION_SWALLOWING = 0x1; 2879 const DWORD EXCEPTION_SWALLOWING = 0x1;
@@ -2885,13 +2881,13 @@ void EnableCrashingOnCrashes()
2885 HMODULE kernel32 = LoadLibraryA("kernel32.dll"); 2881 HMODULE kernel32 = LoadLibraryA("kernel32.dll");
2886 tGetPolicy pGetPolicy = (tGetPolicy)GetProcAddress(kernel32, "GetProcessUserModeExceptionPolicy"); 2882 tGetPolicy pGetPolicy = (tGetPolicy)GetProcAddress(kernel32, "GetProcessUserModeExceptionPolicy");
2887 tSetPolicy pSetPolicy = (tSetPolicy)GetProcAddress(kernel32, "SetProcessUserModeExceptionPolicy"); 2883 tSetPolicy pSetPolicy = (tSetPolicy)GetProcAddress(kernel32, "SetProcessUserModeExceptionPolicy");
2888 if (pGetPolicy && pSetPolicy) 2884 if( pGetPolicy && pSetPolicy)
2889 { 2885 {
2890 DWORD dwFlags; 2886 DWORD dwFlags;
2891 if (pGetPolicy(&dwFlags)) 2887 if( pGetPolicy( &dwFlags))
2892 { 2888 {
2893 // Turn off the filter 2889 // Turn off the filter
2894 pSetPolicy(dwFlags & ~EXCEPTION_SWALLOWING); 2890 pSetPolicy( dwFlags & ~EXCEPTION_SWALLOWING);
2895 } 2891 }
2896 } 2892 }
2897#endif // PLATFORM_WIN32 2893#endif // PLATFORM_WIN32
@@ -2906,21 +2902,11 @@ int LANES_API luaopen_lanes_core( lua_State* L)
2906 2902
2907 // Create main module interface table 2903 // Create main module interface table
2908 // we only have 1 closure, which must be called to configure Lanes 2904 // we only have 1 closure, which must be called to configure Lanes
2909 lua_newtable(L); // M 2905 lua_newtable( L); // M
2910 lua_pushvalue(L, 1); // M "lanes.core" 2906 lua_pushvalue( L, 1); // M "lanes.core"
2911 lua_pushvalue(L, -2); // M "lanes.core" M 2907 lua_pushvalue( L, -2); // M "lanes.core" M
2912 lua_pushcclosure( L, LG_configure, 2); // M LG_configure() 2908 lua_pushcclosure( L, LG_configure, 2); // M LG_configure()
2913 if( s_initCount == 0) 2909 lua_setfield( L, -2, "configure"); // M
2914 {
2915 lua_setfield( L, -2, "configure"); // M
2916 }
2917 else // already initialized: call it immediately and be done
2918 {
2919 // any parameter value will do, they will be ignored
2920 lua_pushinteger( L, 666); // M LG_configure() 666
2921 lua_pushnil( L); // M LG_configure() 666 nil
2922 lua_call( L, 2, 0); // M
2923 }
2924 2910
2925 STACK_END( L, 1); 2911 STACK_END( L, 1);
2926 return 1; 2912 return 1;