diff options
author | benoit-germain <bnt.germain@gmail.com> | 2012-09-11 10:23:15 +0300 |
---|---|---|
committer | benoit-germain <bnt.germain@gmail.com> | 2012-09-11 10:23:15 +0300 |
commit | 8697b3a058f4c58e3a463c77e10cb98fe318f26c (patch) | |
tree | ac7f874c3cf7b4f9659d44a52165ee5809cf0904 /src | |
parent | 242feeb342f68999b02c2b8dc4614abefdab8431 (diff) | |
download | lanes-8697b3a058f4c58e3a463c77e10cb98fe318f26c.tar.gz lanes-8697b3a058f4c58e3a463c77e10cb98fe318f26c.tar.bz2 lanes-8697b3a058f4c58e3a463c77e10cb98fe318f26c.zip |
fixed a bad forward declaration
Diffstat (limited to 'src')
-rw-r--r-- | src/lanes.c | 183 |
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 | ||
198 | static 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 | |||
1037 | typedef enum | ||
1038 | { | ||
1039 | CR_Timeout, | ||
1040 | CR_Cancelled, | ||
1041 | CR_Killed | ||
1042 | } cancel_result; | ||
1043 | |||
1044 | static 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 | ||
1016 | static MUTEX_T selfdestruct_cs; | 1091 | static 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 | |||
1975 | typedef enum | ||
1976 | { | ||
1977 | CR_Timeout, | ||
1978 | CR_Cancelled, | ||
1979 | CR_Killed | ||
1980 | } cancel_result; | ||
1981 | |||
1982 | static 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 | |||
2029 | LUAG_FUNC( thread_cancel) | 2032 | LUAG_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 | ||
2402 | static const struct luaL_Reg lanes_functions [] = { | 2411 | static const struct luaL_Reg lanes_functions [] = { |
2403 | {"linda", LG_linda}, | 2412 | {"linda", LG_linda}, |