diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-12-13 13:07:53 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-12-13 13:07:53 -0200 |
commit | fdc25a1ebfe9968dcec390dd556375105aa0be40 (patch) | |
tree | 43759131636a501ec92475d453fd1a1c73bc8090 /lcorolib.c | |
parent | 3b06f983ae0e57b90cdeb500c84bb524e5c3635b (diff) | |
download | lua-fdc25a1ebfe9968dcec390dd556375105aa0be40.tar.gz lua-fdc25a1ebfe9968dcec390dd556375105aa0be40.tar.bz2 lua-fdc25a1ebfe9968dcec390dd556375105aa0be40.zip |
New functions 'lua_resetthread' and 'coroutine.kill'
New functions to reset/kill a thread/coroutine, mainly (only?) to
close any pending to-be-closed variable. ('lua_resetthread' also
allows a thread to be reused...)
Diffstat (limited to 'lcorolib.c')
-rw-r--r-- | lcorolib.c | 58 |
1 files changed, 46 insertions, 12 deletions
@@ -107,29 +107,40 @@ static int luaB_yield (lua_State *L) { | |||
107 | } | 107 | } |
108 | 108 | ||
109 | 109 | ||
110 | static int luaB_costatus (lua_State *L) { | 110 | #define COS_RUN 0 |
111 | lua_State *co = getco(L); | 111 | #define COS_DEAD 1 |
112 | if (L == co) lua_pushliteral(L, "running"); | 112 | #define COS_YIELD 2 |
113 | #define COS_NORM 3 | ||
114 | |||
115 | |||
116 | static const char *statname[] = {"running", "dead", "suspended", "normal"}; | ||
117 | |||
118 | |||
119 | static int auxstatus (lua_State *L, lua_State *co) { | ||
120 | if (L == co) return COS_RUN; | ||
113 | else { | 121 | else { |
114 | switch (lua_status(co)) { | 122 | switch (lua_status(co)) { |
115 | case LUA_YIELD: | 123 | case LUA_YIELD: |
116 | lua_pushliteral(L, "suspended"); | 124 | return COS_YIELD; |
117 | break; | ||
118 | case LUA_OK: { | 125 | case LUA_OK: { |
119 | lua_Debug ar; | 126 | lua_Debug ar; |
120 | if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ | 127 | if (lua_getstack(co, 0, &ar)) /* does it have frames? */ |
121 | lua_pushliteral(L, "normal"); /* it is running */ | 128 | return COS_NORM; /* it is running */ |
122 | else if (lua_gettop(co) == 0) | 129 | else if (lua_gettop(co) == 0) |
123 | lua_pushliteral(L, "dead"); | 130 | return COS_DEAD; |
124 | else | 131 | else |
125 | lua_pushliteral(L, "suspended"); /* initial state */ | 132 | return COS_YIELD; /* initial state */ |
126 | break; | ||
127 | } | 133 | } |
128 | default: /* some error occurred */ | 134 | default: /* some error occurred */ |
129 | lua_pushliteral(L, "dead"); | 135 | return COS_DEAD; |
130 | break; | ||
131 | } | 136 | } |
132 | } | 137 | } |
138 | } | ||
139 | |||
140 | |||
141 | static int luaB_costatus (lua_State *L) { | ||
142 | lua_State *co = getco(L); | ||
143 | lua_pushstring(L, statname[auxstatus(L, co)]); | ||
133 | return 1; | 144 | return 1; |
134 | } | 145 | } |
135 | 146 | ||
@@ -147,6 +158,28 @@ static int luaB_corunning (lua_State *L) { | |||
147 | } | 158 | } |
148 | 159 | ||
149 | 160 | ||
161 | static int luaB_kill (lua_State *L) { | ||
162 | lua_State *co = getco(L); | ||
163 | int status = auxstatus(L, co); | ||
164 | switch (status) { | ||
165 | case COS_DEAD: case COS_YIELD: { | ||
166 | status = lua_resetthread(co); | ||
167 | if (status == LUA_OK) { | ||
168 | lua_pushboolean(L, 1); | ||
169 | return 1; | ||
170 | } | ||
171 | else { | ||
172 | lua_pushboolean(L, 0); | ||
173 | lua_xmove(co, L, 1); /* copy error message */ | ||
174 | return 2; | ||
175 | } | ||
176 | } | ||
177 | default: /* normal or running coroutine */ | ||
178 | return luaL_error(L, "cannot kill a %s coroutine", statname[status]); | ||
179 | } | ||
180 | } | ||
181 | |||
182 | |||
150 | static const luaL_Reg co_funcs[] = { | 183 | static const luaL_Reg co_funcs[] = { |
151 | {"create", luaB_cocreate}, | 184 | {"create", luaB_cocreate}, |
152 | {"resume", luaB_coresume}, | 185 | {"resume", luaB_coresume}, |
@@ -155,6 +188,7 @@ static const luaL_Reg co_funcs[] = { | |||
155 | {"wrap", luaB_cowrap}, | 188 | {"wrap", luaB_cowrap}, |
156 | {"yield", luaB_yield}, | 189 | {"yield", luaB_yield}, |
157 | {"isyieldable", luaB_yieldable}, | 190 | {"isyieldable", luaB_yieldable}, |
191 | {"kill", luaB_kill}, | ||
158 | {NULL, NULL} | 192 | {NULL, NULL} |
159 | }; | 193 | }; |
160 | 194 | ||