aboutsummaryrefslogtreecommitdiff
path: root/lcorolib.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-12-13 13:07:53 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-12-13 13:07:53 -0200
commitfdc25a1ebfe9968dcec390dd556375105aa0be40 (patch)
tree43759131636a501ec92475d453fd1a1c73bc8090 /lcorolib.c
parent3b06f983ae0e57b90cdeb500c84bb524e5c3635b (diff)
downloadlua-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.c58
1 files changed, 46 insertions, 12 deletions
diff --git a/lcorolib.c b/lcorolib.c
index 34462b53..cdb5fedc 100644
--- a/lcorolib.c
+++ b/lcorolib.c
@@ -107,29 +107,40 @@ static int luaB_yield (lua_State *L) {
107} 107}
108 108
109 109
110static 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
116static const char *statname[] = {"running", "dead", "suspended", "normal"};
117
118
119static 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
141static 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
161static 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
150static const luaL_Reg co_funcs[] = { 183static 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