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}, |
