aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbenoit-germain <bnt.germain@gmail.com>2012-09-11 10:23:15 +0300
committerbenoit-germain <bnt.germain@gmail.com>2012-09-11 10:23:15 +0300
commit8697b3a058f4c58e3a463c77e10cb98fe318f26c (patch)
treeac7f874c3cf7b4f9659d44a52165ee5809cf0904 /src
parent242feeb342f68999b02c2b8dc4614abefdab8431 (diff)
downloadlanes-8697b3a058f4c58e3a463c77e10cb98fe318f26c.tar.gz
lanes-8697b3a058f4c58e3a463c77e10cb98fe318f26c.tar.bz2
lanes-8697b3a058f4c58e3a463c77e10cb98fe318f26c.zip
fixed a bad forward declaration
Diffstat (limited to 'src')
-rw-r--r--src/lanes.c183
1 files changed, 96 insertions, 87 deletions
diff --git a/src/lanes.c b/src/lanes.c
index 462999f..3ac085d 100644
--- a/src/lanes.c
+++ b/src/lanes.c
@@ -195,9 +195,6 @@ struct s_Linda;
195 } 195 }
196#endif 196#endif
197 197
198static bool_t thread_cancel( struct s_lane *s, double secs, bool_t force );
199
200
201/* 198/*
202* Push a table stored in registry onto Lua stack. 199* Push a table stored in registry onto Lua stack.
203* 200*
@@ -228,9 +225,11 @@ static bool_t push_registry_table( lua_State *L, void *key, bool_t create ) {
228 return TRUE; // table pushed 225 return TRUE; // table pushed
229} 226}
230 227
231 228/*
232/*---=== Linda ===--- 229 * ###############################################################################################
233*/ 230 * ############################################ Linda ############################################
231 * ###############################################################################################
232 */
234 233
235/* 234/*
236* Actual data is kept within a keeper state, which is hashed by the 's_Linda' 235* Actual data is kept within a keeper state, which is hashed by the 's_Linda'
@@ -916,9 +915,11 @@ LUAG_FUNC( linda)
916 return luaG_deep_userdata( L, linda_id); 915 return luaG_deep_userdata( L, linda_id);
917} 916}
918 917
919 918/*
920/*---=== Finalizer ===--- 919 * ###############################################################################################
921*/ 920 * ########################################## Finalizer ##########################################
921 * ###############################################################################################
922 */
922 923
923//--- 924//---
924// void= finalizer( finalizer_func ) 925// void= finalizer( finalizer_func )
@@ -1009,9 +1010,83 @@ static int run_finalizers( lua_State *L, int lua_rc )
1009 return rc; 1010 return rc;
1010} 1011}
1011 1012
1013/*
1014 * ###############################################################################################
1015 * ########################################### Threads ###########################################
1016 * ###############################################################################################
1017 */
1012 1018
1013/*---=== Threads ===--- 1019//---
1014*/ 1020// = thread_cancel( lane_ud [,timeout_secs=0.0] [,force_kill_bool=false] )
1021//
1022// The originator thread asking us specifically to cancel the other thread.
1023//
1024// 'timeout': <0: wait forever, until the lane is finished
1025// 0.0: just signal it to cancel, no time waited
1026// >0: time to wait for the lane to detect cancellation
1027//
1028// 'force_kill': if true, and lane does not detect cancellation within timeout,
1029// it is forcefully killed. Using this with 0.0 timeout means just kill
1030// (unless the lane is already finished).
1031//
1032// Returns: true if the lane was already finished (DONE/ERROR_ST/CANCELLED) or if we
1033// managed to cancel it.
1034// false if the cancellation timed out, or a kill was needed.
1035//
1036
1037typedef enum
1038{
1039 CR_Timeout,
1040 CR_Cancelled,
1041 CR_Killed
1042} cancel_result;
1043
1044static cancel_result thread_cancel( struct s_lane *s, double secs, bool_t force)
1045{
1046 cancel_result result;
1047
1048 // remember that lanes are not transferable: only one thread can cancel a lane, so no multithreading issue here
1049 // We can read 's->status' without locks, but not wait for it (if Posix no PTHREAD_TIMEDJOIN)
1050 if( s->mstatus == KILLED)
1051 {
1052 result = CR_Killed;
1053 }
1054 else if( s->status < DONE)
1055 {
1056 s->cancel_request = TRUE; // it's now signaled to stop
1057 // signal the linda the wake up the thread so that it can react to the cancel query
1058 // let us hope we never land here with a pointer on a linda that has been destroyed...
1059 {
1060 SIGNAL_T *waiting_on = s->waiting_on;
1061 if( s->status == WAITING && waiting_on != NULL)
1062 {
1063 SIGNAL_ALL( waiting_on);
1064 }
1065 }
1066
1067 result = THREAD_WAIT( &s->thread, secs, &s->done_signal, &s->done_lock, &s->status) ? CR_Cancelled : CR_Timeout;
1068
1069 if( (result == CR_Timeout) && force)
1070 {
1071 // Killing is asynchronous; we _will_ wait for it to be done at
1072 // GC, to make sure the data structure can be released (alternative
1073 // would be use of "cancellation cleanup handlers" that at least
1074 // PThread seems to have).
1075 //
1076 THREAD_KILL( &s->thread);
1077 s->mstatus = KILLED; // mark 'gc' to wait for it
1078 // note that s->status value must remain to whatever it was at the time of the kill
1079 // because we need to know if we can lua_close() the Lua State or not.
1080 result = CR_Killed;
1081 }
1082 }
1083 else
1084 {
1085 // say "ok" by default, including when lane is already done
1086 result = CR_Cancelled;
1087 }
1088 return result;
1089}
1015 1090
1016static MUTEX_T selfdestruct_cs; 1091static MUTEX_T selfdestruct_cs;
1017 // 1092 //
@@ -1954,78 +2029,6 @@ LUAG_FUNC( thread_gc)
1954 return 0; 2029 return 0;
1955} 2030}
1956 2031
1957//---
1958// = thread_cancel( lane_ud [,timeout_secs=0.0] [,force_kill_bool=false] )
1959//
1960// The originator thread asking us specifically to cancel the other thread.
1961//
1962// 'timeout': <0: wait forever, until the lane is finished
1963// 0.0: just signal it to cancel, no time waited
1964// >0: time to wait for the lane to detect cancellation
1965//
1966// 'force_kill': if true, and lane does not detect cancellation within timeout,
1967// it is forcefully killed. Using this with 0.0 timeout means just kill
1968// (unless the lane is already finished).
1969//
1970// Returns: true if the lane was already finished (DONE/ERROR_ST/CANCELLED) or if we
1971// managed to cancel it.
1972// false if the cancellation timed out, or a kill was needed.
1973//
1974
1975typedef enum
1976{
1977 CR_Timeout,
1978 CR_Cancelled,
1979 CR_Killed
1980} cancel_result;
1981
1982static cancel_result thread_cancel( struct s_lane *s, double secs, bool_t force)
1983{
1984 cancel_result result;
1985
1986 // remember that lanes are not transferable: only one thread can cancel a lane, so no multithreading issue here
1987 // We can read 's->status' without locks, but not wait for it (if Posix no PTHREAD_TIMEDJOIN)
1988 if( s->mstatus == KILLED)
1989 {
1990 result = CR_Killed;
1991 }
1992 else if( s->status < DONE)
1993 {
1994 s->cancel_request = TRUE; // it's now signaled to stop
1995 // signal the linda the wake up the thread so that it can react to the cancel query
1996 // let us hope we never land here with a pointer on a linda that has been destroyed...
1997 {
1998 SIGNAL_T *waiting_on = s->waiting_on;
1999 if( s->status == WAITING && waiting_on != NULL)
2000 {
2001 SIGNAL_ALL( waiting_on);
2002 }
2003 }
2004
2005 result = THREAD_WAIT( &s->thread, secs, &s->done_signal, &s->done_lock, &s->status) ? CR_Cancelled : CR_Timeout;
2006
2007 if( (result == CR_Timeout) && force)
2008 {
2009 // Killing is asynchronous; we _will_ wait for it to be done at
2010 // GC, to make sure the data structure can be released (alternative
2011 // would be use of "cancellation cleanup handlers" that at least
2012 // PThread seems to have).
2013 //
2014 THREAD_KILL( &s->thread);
2015 s->mstatus = KILLED; // mark 'gc' to wait for it
2016 // note that s->status value must remain to whatever it was at the time of the kill
2017 // because we need to know if we can lua_close() the Lua State or not.
2018 result = CR_Killed;
2019 }
2020 }
2021 else
2022 {
2023 // say "ok" by default, including when lane is already done
2024 result = CR_Cancelled;
2025 }
2026 return result;
2027}
2028
2029LUAG_FUNC( thread_cancel) 2032LUAG_FUNC( thread_cancel)
2030{ 2033{
2031 if( lua_gettop( L) < 1 || lua_type( L, 1) != LUA_TUSERDATA) 2034 if( lua_gettop( L) < 1 || lua_type( L, 1) != LUA_TUSERDATA)
@@ -2336,8 +2339,11 @@ LUAG_FUNC( thread_index)
2336 return 0; 2339 return 0;
2337} 2340}
2338 2341
2339/*---=== Timer support ===--- 2342/*
2340*/ 2343 * ###############################################################################################
2344 * ######################################## Timer support ########################################
2345 * ###############################################################################################
2346 */
2341 2347
2342/* 2348/*
2343* secs= now_secs() 2349* secs= now_secs()
@@ -2396,8 +2402,11 @@ LUAG_FUNC( wakeup_conv )
2396 return 1; 2402 return 1;
2397} 2403}
2398 2404
2399/*---=== Module linkage ===--- 2405/*
2400*/ 2406 * ###############################################################################################
2407 * ######################################## Module linkage #######################################
2408 * ###############################################################################################
2409 */
2401 2410
2402static const struct luaL_Reg lanes_functions [] = { 2411static const struct luaL_Reg lanes_functions [] = {
2403 {"linda", LG_linda}, 2412 {"linda", LG_linda},