summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES3
-rw-r--r--src/keeper.c33
-rw-r--r--src/keeper.h1
-rw-r--r--src/lanes.c6
-rw-r--r--src/lanes.lua2
5 files changed, 24 insertions, 21 deletions
diff --git a/CHANGES b/CHANGES
index f6f5268..b2882e7 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,8 @@
1CHANGES: 1CHANGES:
2 2
3CHANGE 43: BGe 09-Aug-2012
4 * fix possible crash at application shutdown when a race condition causes linda objects to be collected after the keeper states are cleaned up.
5
3CHANGE 42: BGe 06-Aug-2012 6CHANGE 42: BGe 06-Aug-2012
4 * lanes.linda() accepts an optional name for debug purposes 7 * lanes.linda() accepts an optional name for debug purposes
5 8
diff --git a/src/keeper.c b/src/keeper.c
index 2404520..28dc338 100644
--- a/src/keeper.c
+++ b/src/keeper.c
@@ -63,6 +63,21 @@
63static struct s_Keeper *GKeepers = NULL; 63static struct s_Keeper *GKeepers = NULL;
64static int GNbKeepers = 0; 64static int GNbKeepers = 0;
65 65
66static void atexit_close_keepers(void)
67{
68 int i;
69 for( i = 0; i < GNbKeepers; ++ i)
70 {
71 lua_close( GKeepers[i].L);
72 GKeepers[i].L = 0;
73 //assert( GKeepers[i].count == 0);
74 MUTEX_FREE( &GKeepers[i].lock_);
75 }
76 if( GKeepers) free( GKeepers);
77 GKeepers = NULL;
78 GNbKeepers = 0;
79}
80
66/* 81/*
67* Initialize keeper states 82* Initialize keeper states
68* 83*
@@ -118,6 +133,9 @@ char const* init_keepers( int const _nbKeepers, lua_CFunction _on_state_create)
118 GKeepers[i].L = K; 133 GKeepers[i].L = K;
119 //GKeepers[i].count = 0; 134 //GKeepers[i].count = 0;
120 } 135 }
136 // call close_keepers at the very last as we want to be sure no thread is GCing after.
137 // (and therefore may perform linda object dereferencing after keepers are gone)
138 atexit( atexit_close_keepers);
121 return NULL; // ok 139 return NULL; // ok
122} 140}
123 141
@@ -264,18 +282,3 @@ int keeper_call( lua_State *K, char const *func_name, lua_State *L, void *linda,
264 lua_settop( K, Ktos); 282 lua_settop( K, Ktos);
265 return retvals; 283 return retvals;
266} 284}
267
268void close_keepers(void)
269{
270 int i;
271 for( i = 0; i < GNbKeepers; ++ i)
272 {
273 lua_close( GKeepers[i].L);
274 GKeepers[i].L = 0;
275 //assert( GKeepers[i].count == 0);
276 MUTEX_FREE( &GKeepers[i].lock_);
277 }
278 if( GKeepers) free( GKeepers);
279 GKeepers = NULL;
280 GNbKeepers = 0;
281}
diff --git a/src/keeper.h b/src/keeper.h
index 0990846..6c4c6f9 100644
--- a/src/keeper.h
+++ b/src/keeper.h
@@ -14,7 +14,6 @@ struct s_Keeper *keeper_acquire( const void *ptr);
14void keeper_release( struct s_Keeper *K); 14void keeper_release( struct s_Keeper *K);
15void keeper_toggle_nil_sentinels( lua_State *L, int _val_i, int _nil_to_sentinel); 15void keeper_toggle_nil_sentinels( lua_State *L, int _val_i, int _nil_to_sentinel);
16int keeper_call( lua_State *K, char const *func_name, lua_State *L, void *linda, uint_t starting_index); 16int keeper_call( lua_State *K, char const *func_name, lua_State *L, void *linda, uint_t starting_index);
17void close_keepers(void);
18 17
19 18
20#endif // __keeper_h__ \ No newline at end of file 19#endif // __keeper_h__ \ No newline at end of file
diff --git a/src/lanes.c b/src/lanes.c
index b65c6fa..262a497 100644
--- a/src/lanes.c
+++ b/src/lanes.c
@@ -1070,7 +1070,7 @@ volatile DEEP_PRELUDE *timer_deep; // = NULL
1070/* 1070/*
1071* Process end; cancel any still free-running threads 1071* Process end; cancel any still free-running threads
1072*/ 1072*/
1073static int selfdestruct_atexit( lua_State *L) 1073static int selfdestruct_gc( lua_State *L)
1074{ 1074{
1075 (void)L; // unused 1075 (void)L; // unused
1076 if (selfdestruct_first == SELFDESTRUCT_END) return 0; // no free-running threads 1076 if (selfdestruct_first == SELFDESTRUCT_END) return 0; // no free-running threads
@@ -1214,7 +1214,6 @@ static int selfdestruct_atexit( lua_State *L)
1214 DEBUGEXEC(fprintf( stderr, "Killed %d lane(s) at process end.\n", n )); 1214 DEBUGEXEC(fprintf( stderr, "Killed %d lane(s) at process end.\n", n ));
1215#endif 1215#endif
1216 } 1216 }
1217 close_keepers();
1218 return 0; 1217 return 0;
1219} 1218}
1220 1219
@@ -2363,7 +2362,6 @@ static void init_once_LOCKED( lua_State* L, volatile DEEP_PRELUDE** timer_deep_r
2363 // Selfdestruct chain handling 2362 // Selfdestruct chain handling
2364 // 2363 //
2365 MUTEX_INIT( &selfdestruct_cs ); 2364 MUTEX_INIT( &selfdestruct_cs );
2366 //atexit( selfdestruct_atexit );
2367 2365
2368 //--- 2366 //---
2369 // Linux needs SCHED_RR to change thread priorities, and that is only 2367 // Linux needs SCHED_RR to change thread priorities, and that is only
@@ -2421,7 +2419,7 @@ static void init_once_LOCKED( lua_State* L, volatile DEEP_PRELUDE** timer_deep_r
2421 { 2419 {
2422 lua_newuserdata( L, 1); 2420 lua_newuserdata( L, 1);
2423 lua_newtable( L); 2421 lua_newtable( L);
2424 lua_pushcfunction( L, selfdestruct_atexit); 2422 lua_pushcfunction( L, selfdestruct_gc);
2425 lua_setfield( L, -2, "__gc"); 2423 lua_setfield( L, -2, "__gc");
2426 lua_pushliteral( L, "AtExit"); 2424 lua_pushliteral( L, "AtExit");
2427 lua_setfield( L, -2, "__metatable"); 2425 lua_setfield( L, -2, "__metatable");
diff --git a/src/lanes.lua b/src/lanes.lua
index 8cd3737..e6400df 100644
--- a/src/lanes.lua
+++ b/src/lanes.lua
@@ -255,7 +255,7 @@ end
255-- We let the C code attach methods to userdata directly 255-- We let the C code attach methods to userdata directly
256 256
257----- 257-----
258-- lanes.linda() -> linda_ud 258-- lanes.linda(["name"]) -> linda_ud
259-- 259--
260-- PUBLIC LANES API 260-- PUBLIC LANES API
261local linda = mm.linda 261local linda = mm.linda