aboutsummaryrefslogtreecommitdiff
path: root/src/lanes.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lanes.c')
-rw-r--r--src/lanes.c102
1 files changed, 56 insertions, 46 deletions
diff --git a/src/lanes.c b/src/lanes.c
index f4bef7b..16a8edc 100644
--- a/src/lanes.c
+++ b/src/lanes.c
@@ -64,7 +64,7 @@
64 * ... 64 * ...
65 */ 65 */
66 66
67const char *VERSION= "2.0.10"; 67const char *VERSION= "2.0.11";
68 68
69/* 69/*
70=============================================================================== 70===============================================================================
@@ -359,7 +359,8 @@ static const char *init_keepers(void) {
359 lua_State *L= luaL_newstate(); 359 lua_State *L= luaL_newstate();
360 if (!L) return "out of memory"; 360 if (!L) return "out of memory";
361 361
362 luaG_openlibs( L, "io,table" ); // 'io' for debugging messages 362 luaG_openlibs( L, "io,table,package" ); // 'io' for debugging messages, package because we need to require modules exporting idfuncs
363 serialize_require( L);
363 364
364 lua_pushlightuserdata( L, &nil_sentinel ); 365 lua_pushlightuserdata( L, &nil_sentinel );
365 lua_setglobal( L, "nil_sentinel" ); 366 lua_setglobal( L, "nil_sentinel" );
@@ -449,9 +450,9 @@ struct s_Linda {
449 SIGNAL_T write_happened; 450 SIGNAL_T write_happened;
450}; 451};
451 452
452static int LG_linda_id( lua_State* ); 453static void linda_id( lua_State*, char const * const which);
453 454
454#define lua_toLinda(L,n) ((struct s_Linda *)luaG_todeep( L, LG_linda_id, n )) 455#define lua_toLinda(L,n) ((struct s_Linda *)luaG_todeep( L, linda_id, n ))
455 456
456 457
457/* 458/*
@@ -462,7 +463,8 @@ static int LG_linda_id( lua_State* );
462* Returns: 'true' if the value was queued 463* Returns: 'true' if the value was queued
463* 'false' for timeout (only happens when the queue size is limited) 464* 'false' for timeout (only happens when the queue size is limited)
464*/ 465*/
465LUAG_FUNC( linda_send ) { 466LUAG_FUNC( linda_send )
467{
466 struct s_Linda *linda= lua_toLinda( L, 1 ); 468 struct s_Linda *linda= lua_toLinda( L, 1 );
467 bool_t ret; 469 bool_t ret;
468 bool_t cancel= FALSE; 470 bool_t cancel= FALSE;
@@ -750,21 +752,22 @@ LUAG_FUNC( linda_deep ) {
750* Returns a metatable for the proxy objects ('__gc' method not needed; will 752* Returns a metatable for the proxy objects ('__gc' method not needed; will
751* be added by 'luaG_...') 753* be added by 'luaG_...')
752* 754*
755* string= linda_id( "module")
756*
757* Returns the name of the module that a state should require
758* in order to keep a handle on the shared library that exported the idfunc
759*
753* = linda_id( str, ... ) 760* = linda_id( str, ... )
754* 761*
755* For any other strings, the ID function must not react at all. This allows 762* For any other strings, the ID function must not react at all. This allows
756* future extensions of the system. 763* future extensions of the system.
757*/ 764*/
758LUAG_FUNC( linda_id ) { 765static void linda_id( lua_State *L, char const * const which)
759 const char *which= lua_tostring(L,1); 766{
760 767 if (strcmp( which, "new" )==0)
761 if (strcmp( which, "new" )==0) { 768 {
762 struct s_Linda *s; 769 struct s_Linda *s;
763 770
764 /* We don't use any parameters, but one could (they're at [2..TOS])
765 */
766 ASSERT_L( lua_gettop(L)==1 );
767
768 /* The deep data is allocated separately of Lua stack; we might no 771 /* The deep data is allocated separately of Lua stack; we might no
769 * longer be around when last reference to it is being released. 772 * longer be around when last reference to it is being released.
770 * One can use any memory allocation scheme. 773 * One can use any memory allocation scheme.
@@ -776,11 +779,11 @@ LUAG_FUNC( linda_id ) {
776 SIGNAL_INIT( &s->write_happened ); 779 SIGNAL_INIT( &s->write_happened );
777 780
778 lua_pushlightuserdata( L, s ); 781 lua_pushlightuserdata( L, s );
779 return 1; 782 }
780 783 else if (strcmp( which, "delete" )==0)
781 } else if (strcmp( which, "delete" )==0) { 784 {
782 struct s_Keeper *K; 785 struct s_Keeper *K;
783 struct s_Linda *s= lua_touserdata(L,2); 786 struct s_Linda *s= lua_touserdata(L,1);
784 ASSERT_L(s); 787 ASSERT_L(s);
785 788
786 /* Clean associated structures in the keeper state. 789 /* Clean associated structures in the keeper state.
@@ -797,18 +800,20 @@ LUAG_FUNC( linda_id ) {
797 SIGNAL_FREE( &s->read_happened ); 800 SIGNAL_FREE( &s->read_happened );
798 SIGNAL_FREE( &s->write_happened ); 801 SIGNAL_FREE( &s->write_happened );
799 free(s); 802 free(s);
803 }
804 else if (strcmp( which, "metatable" )==0)
805 {
800 806
801 return 0; 807 STACK_CHECK(L)
802
803 } else if (strcmp( which, "metatable" )==0) {
804
805 STACK_CHECK(L)
806 lua_newtable(L); 808 lua_newtable(L);
807 lua_newtable(L); 809 // metatable is its own index
808 // 810 lua_pushvalue( L, -1);
809 // [-2]: linda metatable 811 lua_setfield( L, -2, "__index");
810 // [-1]: metatable's to-be .__index table 812 // protect metatable from external access
811 813 lua_pushboolean( L, 0);
814 lua_setfield( L, -2, "__metatable");
815 //
816 // [-1]: linda metatable
812 lua_pushcfunction( L, LG_linda_send ); 817 lua_pushcfunction( L, LG_linda_send );
813 lua_setfield( L, -2, "send" ); 818 lua_setfield( L, -2, "send" );
814 819
@@ -827,13 +832,17 @@ LUAG_FUNC( linda_id ) {
827 lua_pushcfunction( L, LG_linda_deep ); 832 lua_pushcfunction( L, LG_linda_deep );
828 lua_setfield( L, -2, "deep" ); 833 lua_setfield( L, -2, "deep" );
829 834
830 lua_setfield( L, -2, "__index" ); 835 STACK_END(L,1)
831 STACK_END(L,1)
832
833 return 1;
834 } 836 }
835 837 else if( strcmp( which, "module") == 0)
836 return 0; // unknown request, be quiet 838 {
839 lua_pushliteral( L, "lua51-lanes");
840 }
841}
842
843LUAG_FUNC( linda)
844{
845 return luaG_deep_userdata( L, linda_id);
837} 846}
838 847
839 848
@@ -1014,8 +1023,10 @@ static void selfdestruct_atexit( void ) {
1014 MUTEX_UNLOCK( &selfdestruct_cs ); 1023 MUTEX_UNLOCK( &selfdestruct_cs );
1015 1024
1016 // Tell the timer thread to check it's cancel request 1025 // Tell the timer thread to check it's cancel request
1017 struct s_Linda *td = timer_deep->deep; 1026 {
1018 SIGNAL_ALL( &td->write_happened); 1027 struct s_Linda *td = timer_deep->deep;
1028 SIGNAL_ALL( &td->write_happened);
1029 }
1019 1030
1020 // When noticing their cancel, the lanes will remove themselves from 1031 // When noticing their cancel, the lanes will remove themselves from
1021 // the selfdestruct chain. 1032 // the selfdestruct chain.
@@ -1855,21 +1866,21 @@ LUAG_FUNC( wakeup_conv )
1855*/ 1866*/
1856 1867
1857static const struct luaL_reg lanes_functions [] = { 1868static const struct luaL_reg lanes_functions [] = {
1858 {"linda_id", LG_linda_id}, 1869 {"linda", LG_linda},
1859 {"thread_status", LG_thread_status}, 1870 {"thread_status", LG_thread_status},
1860 {"thread_join", LG_thread_join}, 1871 {"thread_join", LG_thread_join},
1861 {"thread_cancel", LG_thread_cancel}, 1872 {"thread_cancel", LG_thread_cancel},
1862 {"now_secs", LG_now_secs}, 1873 {"now_secs", LG_now_secs},
1863 {"wakeup_conv", LG_wakeup_conv}, 1874 {"wakeup_conv", LG_wakeup_conv},
1864 {"_single", LG__single}, 1875 {"_single", LG__single},
1865 {"_deep_userdata", luaG_deep_userdata},
1866 {NULL, NULL} 1876 {NULL, NULL}
1867}; 1877};
1868 1878
1869/* 1879/*
1870* One-time initializations 1880* One-time initializations
1871*/ 1881*/
1872static void init_once_LOCKED( lua_State *L, volatile DEEP_PRELUDE ** timer_deep_ref ) { 1882static void init_once_LOCKED( lua_State *L, volatile DEEP_PRELUDE ** timer_deep_ref )
1883{
1873 const char *err; 1884 const char *err;
1874 1885
1875#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) 1886#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC)
@@ -1919,8 +1930,9 @@ static void init_once_LOCKED( lua_State *L, volatile DEEP_PRELUDE ** timer_deep_
1919 } 1930 }
1920 #endif 1931 #endif
1921#endif 1932#endif
1922 err= init_keepers(); 1933 err= init_keepers();
1923 if (err) { 1934 if (err)
1935 {
1924 luaL_error( L, "Unable to initialize: %s", err ); 1936 luaL_error( L, "Unable to initialize: %s", err );
1925 } 1937 }
1926 1938
@@ -1928,13 +1940,11 @@ static void init_once_LOCKED( lua_State *L, volatile DEEP_PRELUDE ** timer_deep_
1928 // 1940 //
1929 ASSERT_L( timer_deep_ref && (!(*timer_deep_ref)) ); 1941 ASSERT_L( timer_deep_ref && (!(*timer_deep_ref)) );
1930 1942
1931 STACK_CHECK(L) 1943 STACK_CHECK(L)
1932 { 1944 {
1933 // proxy_ud= deep_userdata( idfunc ) 1945 // proxy_ud= deep_userdata( idfunc )
1934 // 1946 //
1935 lua_pushcfunction( L, luaG_deep_userdata ); 1947 luaG_deep_userdata( L, linda_id);
1936 lua_pushcfunction( L, LG_linda_id );
1937 lua_call( L, 1 /*args*/, 1 /*retvals*/ );
1938 1948
1939 ASSERT_L( lua_isuserdata(L,-1) ); 1949 ASSERT_L( lua_isuserdata(L,-1) );
1940 1950
@@ -1950,7 +1960,7 @@ static void init_once_LOCKED( lua_State *L, volatile DEEP_PRELUDE ** timer_deep_
1950 lua_rawset(L, LUA_REGISTRYINDEX); 1960 lua_rawset(L, LUA_REGISTRYINDEX);
1951 1961
1952 } 1962 }
1953 STACK_END(L,0) 1963 STACK_END(L,0)
1954} 1964}
1955 1965
1956int 1966int
@@ -2014,7 +2024,7 @@ __declspec(dllexport)
2014 lua_pushcclosure( L, LG_thread_new, 1 ); // metatable as closure param 2024 lua_pushcclosure( L, LG_thread_new, 1 ); // metatable as closure param
2015 lua_setfield(L, -2, "thread_new"); 2025 lua_setfield(L, -2, "thread_new");
2016 2026
2017 luaG_push_proxy( L, LG_linda_id, (DEEP_PRELUDE *) timer_deep ); 2027 luaG_push_proxy( L, linda_id, (DEEP_PRELUDE *) timer_deep );
2018 lua_setfield(L, -2, "timer_gateway"); 2028 lua_setfield(L, -2, "timer_gateway");
2019 2029
2020 lua_pushstring(L, VERSION); 2030 lua_pushstring(L, VERSION);