diff options
Diffstat (limited to 'src/lanes.c')
-rw-r--r-- | src/lanes.c | 120 |
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 | ||
55 | char const* VERSION = "3.6.5"; | 55 | char 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! |
2878 | void EnableCrashingOnCrashes() | 2874 | static 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; |