diff options
author | Benoit Germain <bnt period germain arrobase gmail period com> | 2014-02-17 11:05:19 +0100 |
---|---|---|
committer | Benoit Germain <bnt period germain arrobase gmail period com> | 2014-02-17 11:05:19 +0100 |
commit | 47eb3f94373a13ac9f204ca65dfde602f53bdc1a (patch) | |
tree | 95d7d7a52ca92e6527d46d97207d3f079611a355 /src/lanes.c | |
parent | 32ad991eb8c590472607d61e9a831d2ca9db05c5 (diff) | |
download | lanes-47eb3f94373a13ac9f204ca65dfde602f53bdc1a.tar.gz lanes-47eb3f94373a13ac9f204ca65dfde602f53bdc1a.tar.bz2 lanes-47eb3f94373a13ac9f204ca65dfde602f53bdc1a.zip |
Deep userdata support improvements
* bumped version to 3.9.0
* keepers now require "package", receive package.path & package.cpath,
and call on_state_create() if it is a C function
* changed the deep public API (improved deep idfunc signature, renamed
luaG_deep_userdata to luaG_newdeepuserdata)
* if an error occurs while copying a deep userdata, don't raise inside
the keeper state
* fixed situations where raised errors could lead to memory leaks (deep
gc)
Diffstat (limited to 'src/lanes.c')
-rw-r--r-- | src/lanes.c | 286 |
1 files changed, 149 insertions, 137 deletions
diff --git a/src/lanes.c b/src/lanes.c index dbb0a82..597ac4b 100644 --- a/src/lanes.c +++ b/src/lanes.c | |||
@@ -52,7 +52,7 @@ | |||
52 | * ... | 52 | * ... |
53 | */ | 53 | */ |
54 | 54 | ||
55 | char const* VERSION = "3.8.5"; | 55 | char const* VERSION = "3.9.0"; |
56 | 56 | ||
57 | /* | 57 | /* |
58 | =============================================================================== | 58 | =============================================================================== |
@@ -422,11 +422,11 @@ struct s_Linda | |||
422 | char name[1]; | 422 | char name[1]; |
423 | }; | 423 | }; |
424 | 424 | ||
425 | static void linda_id( lua_State*, char const * const which); | 425 | static void* linda_id( lua_State*, enum eDeepOp); |
426 | 426 | ||
427 | static inline struct s_Linda* lua_toLinda( lua_State* L, int idx_) | 427 | static inline struct s_Linda* lua_toLinda( lua_State* L, int idx_) |
428 | { | 428 | { |
429 | struct s_Linda* linda = luaG_todeep( L, linda_id, idx_); | 429 | struct s_Linda* linda = (struct s_Linda*) luaG_todeep( L, linda_id, idx_); |
430 | luaL_argcheck( L, linda != NULL, idx_, "expecting a linda object"); | 430 | luaL_argcheck( L, linda != NULL, idx_, "expecting a linda object"); |
431 | return linda; | 431 | return linda; |
432 | } | 432 | } |
@@ -996,7 +996,7 @@ LUAG_FUNC( linda_deep) | |||
996 | 996 | ||
997 | static int linda_tostring( lua_State* L, int idx_, bool_t opt_) | 997 | static int linda_tostring( lua_State* L, int idx_, bool_t opt_) |
998 | { | 998 | { |
999 | struct s_Linda* linda = luaG_todeep( L, linda_id, idx_); | 999 | struct s_Linda* linda = (struct s_Linda*) luaG_todeep( L, linda_id, idx_); |
1000 | if( !opt_) | 1000 | if( !opt_) |
1001 | { | 1001 | { |
1002 | luaL_argcheck( L, linda, idx_, "expecting a linda object"); | 1002 | luaL_argcheck( L, linda, idx_, "expecting a linda object"); |
@@ -1084,122 +1084,127 @@ LUAG_FUNC( linda_dump) | |||
1084 | * For any other strings, the ID function must not react at all. This allows | 1084 | * For any other strings, the ID function must not react at all. This allows |
1085 | * future extensions of the system. | 1085 | * future extensions of the system. |
1086 | */ | 1086 | */ |
1087 | static void linda_id( lua_State* L, char const* const which) | 1087 | static void* linda_id( lua_State* L, enum eDeepOp op_) |
1088 | { | 1088 | { |
1089 | if( strcmp( which, "new" ) == 0) | 1089 | switch( op_) |
1090 | { | 1090 | { |
1091 | struct s_Linda* s; | 1091 | case eDO_new: |
1092 | size_t name_len = 0; | ||
1093 | char const* linda_name = NULL; | ||
1094 | int const top = lua_gettop( L); | ||
1095 | |||
1096 | if( top > 0 && lua_type( L, top) == LUA_TSTRING) | ||
1097 | { | 1092 | { |
1098 | linda_name = lua_tostring( L, top); | 1093 | struct s_Linda* s; |
1099 | name_len = strlen( linda_name); | 1094 | size_t name_len = 0; |
1100 | } | 1095 | char const* linda_name = NULL; |
1096 | int const top = lua_gettop( L); | ||
1101 | 1097 | ||
1102 | /* The deep data is allocated separately of Lua stack; we might no | 1098 | if( top > 0 && lua_type( L, top) == LUA_TSTRING) |
1103 | * longer be around when last reference to it is being released. | 1099 | { |
1104 | * One can use any memory allocation scheme. | 1100 | linda_name = lua_tolstring( L, top, &name_len); |
1105 | */ | 1101 | } |
1106 | s = (struct s_Linda*) malloc( sizeof(struct s_Linda) + name_len); // terminating 0 is already included | ||
1107 | ASSERT_L( s); | ||
1108 | |||
1109 | SIGNAL_INIT( &s->read_happened); | ||
1110 | SIGNAL_INIT( &s->write_happened); | ||
1111 | s->simulate_cancel = CANCEL_NONE; | ||
1112 | s->name[0] = 0; | ||
1113 | memcpy( s->name, linda_name, name_len ? name_len + 1 : 0); | ||
1114 | 1102 | ||
1115 | lua_pushlightuserdata( L, s); | 1103 | /* The deep data is allocated separately of Lua stack; we might no |
1116 | } | 1104 | * longer be around when last reference to it is being released. |
1117 | else if( strcmp( which, "delete") == 0) | 1105 | * One can use any memory allocation scheme. |
1118 | { | 1106 | */ |
1119 | struct s_Keeper* K; | 1107 | s = (struct s_Linda*) malloc( sizeof(struct s_Linda) + name_len); // terminating 0 is already included |
1120 | struct s_Linda* l = lua_touserdata( L, 1); | 1108 | ASSERT_L( s); |
1121 | ASSERT_L( l); | 1109 | |
1110 | SIGNAL_INIT( &s->read_happened); | ||
1111 | SIGNAL_INIT( &s->write_happened); | ||
1112 | s->simulate_cancel = CANCEL_NONE; | ||
1113 | s->name[0] = 0; | ||
1114 | memcpy( s->name, linda_name, name_len ? name_len + 1 : 0); | ||
1115 | return s; | ||
1116 | } | ||
1122 | 1117 | ||
1123 | /* Clean associated structures in the keeper state. | 1118 | case eDO_delete: |
1124 | */ | ||
1125 | K = keeper_acquire( l); | ||
1126 | if( K && K->L) // can be NULL if this happens during main state shutdown (lanes is GC'ed -> no keepers -> no need to cleanup) | ||
1127 | { | 1119 | { |
1128 | keeper_call( K->L, KEEPER_API( clear), L, l, 0); | 1120 | struct s_Keeper* K; |
1121 | struct s_Linda* l = lua_touserdata( L, 1); | ||
1122 | ASSERT_L( l); | ||
1123 | |||
1124 | /* Clean associated structures in the keeper state. | ||
1125 | */ | ||
1126 | K = keeper_acquire( l); | ||
1127 | if( K && K->L) // can be NULL if this happens during main state shutdown (lanes is GC'ed -> no keepers -> no need to cleanup) | ||
1128 | { | ||
1129 | keeper_call( K->L, KEEPER_API( clear), L, l, 0); | ||
1130 | } | ||
1131 | keeper_release( K); | ||
1132 | |||
1133 | /* There aren't any lanes waiting on these lindas, since all proxies | ||
1134 | * have been gc'ed. Right? | ||
1135 | */ | ||
1136 | SIGNAL_FREE( &l->read_happened); | ||
1137 | SIGNAL_FREE( &l->write_happened); | ||
1138 | free( l); | ||
1139 | return NULL; | ||
1129 | } | 1140 | } |
1130 | keeper_release( K); | ||
1131 | 1141 | ||
1132 | /* There aren't any lanes waiting on these lindas, since all proxies | 1142 | case eDO_metatable: |
1133 | * have been gc'ed. Right? | 1143 | { |
1134 | */ | ||
1135 | SIGNAL_FREE( &l->read_happened); | ||
1136 | SIGNAL_FREE( &l->write_happened); | ||
1137 | free( l); | ||
1138 | } | ||
1139 | else if( strcmp( which, "metatable" ) == 0) | ||
1140 | { | ||
1141 | 1144 | ||
1142 | STACK_CHECK( L); | 1145 | STACK_CHECK( L); |
1143 | lua_newtable( L); | 1146 | lua_newtable( L); |
1144 | // metatable is its own index | 1147 | // metatable is its own index |
1145 | lua_pushvalue( L, -1); | 1148 | lua_pushvalue( L, -1); |
1146 | lua_setfield( L, -2, "__index"); | 1149 | lua_setfield( L, -2, "__index"); |
1147 | 1150 | ||
1148 | // protect metatable from external access | 1151 | // protect metatable from external access |
1149 | lua_pushliteral( L, "Linda"); | 1152 | lua_pushliteral( L, "Linda"); |
1150 | lua_setfield( L, -2, "__metatable"); | 1153 | lua_setfield( L, -2, "__metatable"); |
1151 | 1154 | ||
1152 | lua_pushcfunction( L, LG_linda_tostring); | 1155 | lua_pushcfunction( L, LG_linda_tostring); |
1153 | lua_setfield( L, -2, "__tostring"); | 1156 | lua_setfield( L, -2, "__tostring"); |
1154 | 1157 | ||
1155 | // Decoda __towatch support | 1158 | // Decoda __towatch support |
1156 | lua_pushcfunction( L, LG_linda_dump); | 1159 | lua_pushcfunction( L, LG_linda_dump); |
1157 | lua_setfield( L, -2, "__towatch"); | 1160 | lua_setfield( L, -2, "__towatch"); |
1158 | 1161 | ||
1159 | lua_pushcfunction( L, LG_linda_concat); | 1162 | lua_pushcfunction( L, LG_linda_concat); |
1160 | lua_setfield( L, -2, "__concat"); | 1163 | lua_setfield( L, -2, "__concat"); |
1161 | 1164 | ||
1162 | // [-1]: linda metatable | 1165 | // [-1]: linda metatable |
1163 | lua_pushcfunction( L, LG_linda_send); | 1166 | lua_pushcfunction( L, LG_linda_send); |
1164 | lua_setfield( L, -2, "send"); | 1167 | lua_setfield( L, -2, "send"); |
1165 | 1168 | ||
1166 | lua_pushcfunction( L, LG_linda_receive); | 1169 | lua_pushcfunction( L, LG_linda_receive); |
1167 | lua_setfield( L, -2, "receive"); | 1170 | lua_setfield( L, -2, "receive"); |
1168 | 1171 | ||
1169 | lua_pushcfunction( L, LG_linda_limit); | 1172 | lua_pushcfunction( L, LG_linda_limit); |
1170 | lua_setfield( L, -2, "limit"); | 1173 | lua_setfield( L, -2, "limit"); |
1171 | 1174 | ||
1172 | lua_pushcfunction( L, LG_linda_set); | 1175 | lua_pushcfunction( L, LG_linda_set); |
1173 | lua_setfield( L, -2, "set"); | 1176 | lua_setfield( L, -2, "set"); |
1174 | 1177 | ||
1175 | lua_pushcfunction( L, LG_linda_count); | 1178 | lua_pushcfunction( L, LG_linda_count); |
1176 | lua_setfield( L, -2, "count"); | 1179 | lua_setfield( L, -2, "count"); |
1177 | 1180 | ||
1178 | lua_pushcfunction( L, LG_linda_get); | 1181 | lua_pushcfunction( L, LG_linda_get); |
1179 | lua_setfield( L, -2, "get"); | 1182 | lua_setfield( L, -2, "get"); |
1180 | 1183 | ||
1181 | lua_pushcfunction( L, LG_linda_cancel); | 1184 | lua_pushcfunction( L, LG_linda_cancel); |
1182 | lua_setfield( L, -2, "cancel"); | 1185 | lua_setfield( L, -2, "cancel"); |
1183 | 1186 | ||
1184 | lua_pushcfunction( L, LG_linda_deep); | 1187 | lua_pushcfunction( L, LG_linda_deep); |
1185 | lua_setfield( L, -2, "deep"); | 1188 | lua_setfield( L, -2, "deep"); |
1186 | 1189 | ||
1187 | lua_pushcfunction( L, LG_linda_dump); | 1190 | lua_pushcfunction( L, LG_linda_dump); |
1188 | lua_setfield( L, -2, "dump"); | 1191 | lua_setfield( L, -2, "dump"); |
1189 | 1192 | ||
1190 | lua_pushliteral( L, BATCH_SENTINEL); | 1193 | lua_pushliteral( L, BATCH_SENTINEL); |
1191 | lua_setfield(L, -2, "batched"); | 1194 | lua_setfield(L, -2, "batched"); |
1192 | 1195 | ||
1193 | STACK_END( L, 1); | 1196 | STACK_END( L, 1); |
1194 | } | 1197 | return NULL; |
1195 | else if( strcmp( which, "module") == 0) | 1198 | } |
1196 | { | 1199 | |
1200 | case eDO_module: | ||
1197 | // linda is a special case because we know lanes must be loaded from the main lua state | 1201 | // linda is a special case because we know lanes must be loaded from the main lua state |
1198 | // to be able to ever get here, so we know it will remain loaded as long a the main state is around | 1202 | // to be able to ever get here, so we know it will remain loaded as long a the main state is around |
1199 | // in other words, forever. | 1203 | // in other words, forever. |
1200 | lua_pushnil( L); | 1204 | default: |
1201 | // other idfuncs must push a string naming the module they come from | 1205 | { |
1202 | //lua_pushliteral( L, "lanes.core"); | 1206 | return NULL; |
1207 | } | ||
1203 | } | 1208 | } |
1204 | } | 1209 | } |
1205 | 1210 | ||
@@ -1214,7 +1219,7 @@ LUAG_FUNC( linda) | |||
1214 | luaL_argcheck( L, top <= 1, top, "too many arguments"); | 1219 | luaL_argcheck( L, top <= 1, top, "too many arguments"); |
1215 | if( top == 1) | 1220 | if( top == 1) |
1216 | luaL_checktype( L, 1, LUA_TSTRING); | 1221 | luaL_checktype( L, 1, LUA_TSTRING); |
1217 | return luaG_deep_userdata( L, linda_id); | 1222 | return luaG_newdeepuserdata( L, linda_id); |
1218 | } | 1223 | } |
1219 | 1224 | ||
1220 | /* | 1225 | /* |
@@ -2199,7 +2204,7 @@ LUAG_FUNC( thread_new) | |||
2199 | // which might not be the case if the libs list didn't include lanes.core or "*" | 2204 | // which might not be the case if the libs list didn't include lanes.core or "*" |
2200 | if( strncmp( name, "lanes.core", len) == 0) // this works both both "lanes" and "lanes.core" because of len | 2205 | if( strncmp( name, "lanes.core", len) == 0) // this works both both "lanes" and "lanes.core" because of len |
2201 | { | 2206 | { |
2202 | luaG_copy_one_time_settings( L, L2, name); | 2207 | luaG_copy_one_time_settings( L, L2); |
2203 | } | 2208 | } |
2204 | lua_pushlstring( L2, name, len); // require() name | 2209 | lua_pushlstring( L2, name, len); // require() name |
2205 | if( lua_pcall( L2, 1, 1, 0) != LUA_OK) // ret/errcode | 2210 | if( lua_pcall( L2, 1, 1, 0) != LUA_OK) // ret/errcode |
@@ -2324,8 +2329,8 @@ LUAG_FUNC( thread_new) | |||
2324 | MUTEX_INIT( &s->done_lock); | 2329 | MUTEX_INIT( &s->done_lock); |
2325 | SIGNAL_INIT( &s->done_signal); | 2330 | SIGNAL_INIT( &s->done_signal); |
2326 | #endif // THREADWAIT_METHOD == THREADWAIT_CONDVAR | 2331 | #endif // THREADWAIT_METHOD == THREADWAIT_CONDVAR |
2327 | s->mstatus= NORMAL; | 2332 | s->mstatus = NORMAL; |
2328 | s->selfdestruct_next= NULL; | 2333 | s->selfdestruct_next = NULL; |
2329 | #if HAVE_LANE_TRACKING | 2334 | #if HAVE_LANE_TRACKING |
2330 | s->tracking_next = NULL; | 2335 | s->tracking_next = NULL; |
2331 | #endif // HAVE_LANE_TRACKING | 2336 | #endif // HAVE_LANE_TRACKING |
@@ -2969,7 +2974,7 @@ static void init_once_LOCKED( lua_State* L) | |||
2969 | // proxy_ud= deep_userdata( idfunc ) | 2974 | // proxy_ud= deep_userdata( idfunc ) |
2970 | // | 2975 | // |
2971 | lua_pushliteral( L, "lanes-timer"); // push a name for debug purposes | 2976 | lua_pushliteral( L, "lanes-timer"); // push a name for debug purposes |
2972 | luaG_deep_userdata( L, linda_id); | 2977 | luaG_newdeepuserdata( L, linda_id); |
2973 | STACK_MID( L, 2); | 2978 | STACK_MID( L, 2); |
2974 | lua_remove( L, -2); // remove the name as we no longer need it | 2979 | lua_remove( L, -2); // remove the name as we no longer need it |
2975 | 2980 | ||
@@ -2978,7 +2983,7 @@ static void init_once_LOCKED( lua_State* L) | |||
2978 | // Proxy userdata contents is only a 'DEEP_PRELUDE*' pointer | 2983 | // Proxy userdata contents is only a 'DEEP_PRELUDE*' pointer |
2979 | // | 2984 | // |
2980 | timer_deep = * (DEEP_PRELUDE**) lua_touserdata( L, -1); | 2985 | timer_deep = * (DEEP_PRELUDE**) lua_touserdata( L, -1); |
2981 | ASSERT_L( timer_deep && (timer_deep->refcount == 1) && timer_deep->deep); | 2986 | ASSERT_L( timer_deep && (timer_deep->refcount == 1) && timer_deep->deep && timer_deep->idfunc == linda_id); |
2982 | 2987 | ||
2983 | // The host Lua state must always have a reference to this Linda object in order for the timer_deep pointer to be valid. | 2988 | // The host Lua state must always have a reference to this Linda object in order for the timer_deep pointer to be valid. |
2984 | // So store a reference that we will never actually use. | 2989 | // So store a reference that we will never actually use. |
@@ -3019,7 +3024,7 @@ LUAG_FUNC( configure) | |||
3019 | DEBUGSPEW_CODE( ++ debugspew_indent_depth); | 3024 | DEBUGSPEW_CODE( ++ debugspew_indent_depth); |
3020 | 3025 | ||
3021 | // not in init_once_LOCKED because we can have several hosted "master" Lua states where Lanes is require()d. | 3026 | // not in init_once_LOCKED because we can have several hosted "master" Lua states where Lanes is require()d. |
3022 | lua_getfield( L, 1, "protect_allocator"); // settings protect_allocator | 3027 | lua_getfield( L, 1, "protect_allocator"); // settings protect_allocator |
3023 | if( lua_toboolean( L, -1)) | 3028 | if( lua_toboolean( L, -1)) |
3024 | { | 3029 | { |
3025 | void* ud; | 3030 | void* ud; |
@@ -3033,7 +3038,7 @@ LUAG_FUNC( configure) | |||
3033 | lua_setallocf( L, protected_lua_Alloc, s); | 3038 | lua_setallocf( L, protected_lua_Alloc, s); |
3034 | } | 3039 | } |
3035 | } | 3040 | } |
3036 | lua_pop( L, 1); // settings | 3041 | lua_pop( L, 1); // settings |
3037 | STACK_MID( L, 0); | 3042 | STACK_MID( L, 0); |
3038 | 3043 | ||
3039 | /* | 3044 | /* |
@@ -3075,68 +3080,75 @@ LUAG_FUNC( configure) | |||
3075 | #endif // THREADAPI == THREADAPI_PTHREAD | 3080 | #endif // THREADAPI == THREADAPI_PTHREAD |
3076 | 3081 | ||
3077 | // Retrieve main module interface table | 3082 | // Retrieve main module interface table |
3078 | lua_pushvalue( L, lua_upvalueindex( 2)); // settings M | 3083 | lua_pushvalue( L, lua_upvalueindex( 2)); // settings M |
3079 | // remove configure() (this function) from the module interface | 3084 | // remove configure() (this function) from the module interface |
3080 | lua_pushnil( L); // settings M nil | 3085 | lua_pushnil( L); // settings M nil |
3081 | lua_setfield( L, -2, "configure"); // settings M | 3086 | lua_setfield( L, -2, "configure"); // settings M |
3082 | // add functions to the module's table | 3087 | // add functions to the module's table |
3083 | luaG_registerlibfuncs( L, lanes_functions); | 3088 | luaG_registerlibfuncs( L, lanes_functions); |
3084 | #if HAVE_LANE_TRACKING | 3089 | #if HAVE_LANE_TRACKING |
3085 | // register core.threads() only if settings say it should be available | 3090 | // register core.threads() only if settings say it should be available |
3086 | if( tracking_first != NULL) | 3091 | if( tracking_first != NULL) |
3087 | { | 3092 | { |
3088 | lua_pushcfunction( L, LG_threads); // settings M LG_threads() | 3093 | lua_pushcfunction( L, LG_threads); // settings M LG_threads() |
3089 | lua_setfield( L, -2, "threads"); | 3094 | lua_setfield( L, -2, "threads"); // settings M |
3090 | } | 3095 | } |
3091 | #endif // HAVE_LANE_TRACKING | 3096 | #endif // HAVE_LANE_TRACKING |
3092 | STACK_MID( L, 1); | 3097 | STACK_MID( L, 1); |
3093 | 3098 | ||
3094 | ASSERT_L( timer_deep != NULL); // initialized by init_once_LOCKED | 3099 | { |
3095 | luaG_push_proxy( L, linda_id, (DEEP_PRELUDE*) timer_deep); // settings M timer_deep | 3100 | char const* errmsg; |
3096 | lua_setfield( L, -2, "timer_gateway"); // settings M | 3101 | ASSERT_L( timer_deep != NULL); // initialized by init_once_LOCKED |
3102 | errmsg = push_deep_proxy( L, (DEEP_PRELUDE*) timer_deep, eLM_LaneBody); // settings M timer_deep | ||
3103 | if( errmsg != NULL) | ||
3104 | { | ||
3105 | luaL_error( L, errmsg); | ||
3106 | } | ||
3107 | lua_setfield( L, -2, "timer_gateway"); // settings M | ||
3108 | } | ||
3097 | STACK_MID( L, 1); | 3109 | STACK_MID( L, 1); |
3098 | 3110 | ||
3099 | // prepare the metatable for threads | 3111 | // prepare the metatable for threads |
3100 | // contains keys: { __gc, __index, cached_error, cached_tostring, cancel, join, get_debug_threadname } | 3112 | // contains keys: { __gc, __index, cached_error, cached_tostring, cancel, join, get_debug_threadname } |
3101 | // | 3113 | // |
3102 | if( luaL_newmetatable( L, "Lane")) // settings M mt | 3114 | if( luaL_newmetatable( L, "Lane")) // settings M mt |
3103 | { | 3115 | { |
3104 | lua_pushcfunction( L, LG_thread_gc); // settings M mt LG_thread_gc | 3116 | lua_pushcfunction( L, LG_thread_gc); // settings M mt LG_thread_gc |
3105 | lua_setfield( L, -2, "__gc"); // settings M mt | 3117 | lua_setfield( L, -2, "__gc"); // settings M mt |
3106 | lua_pushcfunction( L, LG_thread_index); // settings M mt LG_thread_index | 3118 | lua_pushcfunction( L, LG_thread_index); // settings M mt LG_thread_index |
3107 | lua_setfield( L, -2, "__index"); // settings M mt | 3119 | lua_setfield( L, -2, "__index"); // settings M mt |
3108 | lua_getglobal( L, "error"); // settings M mt error | 3120 | lua_getglobal( L, "error"); // settings M mt error |
3109 | ASSERT_L( lua_isfunction( L, -1)); | 3121 | ASSERT_L( lua_isfunction( L, -1)); |
3110 | lua_setfield( L, -2, "cached_error"); // settings M mt | 3122 | lua_setfield( L, -2, "cached_error"); // settings M mt |
3111 | lua_getglobal( L, "tostring"); // settings M mt tostring | 3123 | lua_getglobal( L, "tostring"); // settings M mt tostring |
3112 | ASSERT_L( lua_isfunction( L, -1)); | 3124 | ASSERT_L( lua_isfunction( L, -1)); |
3113 | lua_setfield( L, -2, "cached_tostring"); // settings M mt | 3125 | lua_setfield( L, -2, "cached_tostring"); // settings M mt |
3114 | lua_pushcfunction( L, LG_thread_join); // settings M mt LG_thread_join | 3126 | lua_pushcfunction( L, LG_thread_join); // settings M mt LG_thread_join |
3115 | lua_setfield( L, -2, "join"); // settings M mt | 3127 | lua_setfield( L, -2, "join"); // settings M mt |
3116 | lua_pushcfunction( L, LG_get_debug_threadname); // settings M mt LG_get_debug_threadname | 3128 | lua_pushcfunction( L, LG_get_debug_threadname); // settings M mt LG_get_debug_threadname |
3117 | lua_setfield( L, -2, "get_debug_threadname"); // settings M mt | 3129 | lua_setfield( L, -2, "get_debug_threadname"); // settings M mt |
3118 | lua_pushcfunction( L, LG_thread_cancel); // settings M mt LG_thread_cancel | 3130 | lua_pushcfunction( L, LG_thread_cancel); // settings M mt LG_thread_cancel |
3119 | lua_setfield( L, -2, "cancel"); // settings M mt | 3131 | lua_setfield( L, -2, "cancel"); // settings M mt |
3120 | lua_pushliteral( L, "Lane"); // settings M mt "Lane" | 3132 | lua_pushliteral( L, "Lane"); // settings M mt "Lane" |
3121 | lua_setfield( L, -2, "__metatable"); // settings M mt | 3133 | lua_setfield( L, -2, "__metatable"); // settings M mt |
3122 | } | 3134 | } |
3123 | 3135 | ||
3124 | lua_pushcclosure( L, LG_thread_new, 1); // settings M LG_thread_new | 3136 | lua_pushcclosure( L, LG_thread_new, 1); // settings M LG_thread_new |
3125 | lua_setfield( L, -2, "thread_new"); // settings M | 3137 | lua_setfield( L, -2, "thread_new"); // settings M |
3126 | 3138 | ||
3127 | // we can't register 'lanes.require' normally because we want to create an upvalued closure | 3139 | // we can't register 'lanes.require' normally because we want to create an upvalued closure |
3128 | lua_getglobal( L, "require"); // settings M require | 3140 | lua_getglobal( L, "require"); // settings M require |
3129 | lua_pushcclosure( L, LG_require, 1); // settings M lanes.require | 3141 | lua_pushcclosure( L, LG_require, 1); // settings M lanes.require |
3130 | lua_setfield( L, -2, "require"); // settings M | 3142 | lua_setfield( L, -2, "require"); // settings M |
3131 | 3143 | ||
3132 | lua_pushstring(L, VERSION); // settings M VERSION | 3144 | lua_pushstring(L, VERSION); // settings M VERSION |
3133 | lua_setfield(L, -2, "version"); // settings M | 3145 | lua_setfield(L, -2, "version"); // settings M |
3134 | 3146 | ||
3135 | lua_pushinteger(L, THREAD_PRIO_MAX); // settings M THREAD_PRIO_MAX | 3147 | lua_pushinteger(L, THREAD_PRIO_MAX); // settings M THREAD_PRIO_MAX |
3136 | lua_setfield(L, -2, "max_prio"); // settings M | 3148 | lua_setfield(L, -2, "max_prio"); // settings M |
3137 | 3149 | ||
3138 | lua_pushlightuserdata( L, CANCEL_ERROR); // settings M CANCEL_ERROR | 3150 | lua_pushlightuserdata( L, CANCEL_ERROR); // settings M CANCEL_ERROR |
3139 | lua_setfield(L, -2, "cancel_error"); // settings M | 3151 | lua_setfield(L, -2, "cancel_error"); // settings M |
3140 | 3152 | ||
3141 | // register all native functions found in that module in the transferable functions database | 3153 | // register all native functions found in that module in the transferable functions database |
3142 | // we process it before _G because we don't want to find the module when scanning _G (this would generate longer names) | 3154 | // we process it before _G because we don't want to find the module when scanning _G (this would generate longer names) |
@@ -3151,7 +3163,7 @@ LUAG_FUNC( configure) | |||
3151 | // set _R[CONFIG_REGKEY] = settings | 3163 | // set _R[CONFIG_REGKEY] = settings |
3152 | lua_pushvalue( L, -2); // settings M settings | 3164 | lua_pushvalue( L, -2); // settings M settings |
3153 | lua_setfield( L, LUA_REGISTRYINDEX, CONFIG_REGKEY); // settings M | 3165 | lua_setfield( L, LUA_REGISTRYINDEX, CONFIG_REGKEY); // settings M |
3154 | lua_pop( L, 1); // settings | 3166 | lua_pop( L, 1); // settings |
3155 | STACK_END( L, 0); | 3167 | STACK_END( L, 0); |
3156 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: lanes.configure() END\n" INDENT_END, L)); | 3168 | DEBUGSPEW_CODE( fprintf( stderr, INDENT_BEGIN "%p: lanes.configure() END\n" INDENT_END, L)); |
3157 | DEBUGSPEW_CODE( -- debugspew_indent_depth); | 3169 | DEBUGSPEW_CODE( -- debugspew_indent_depth); |