@ -107,29 +107,40 @@ static int luaB_yield (lua_State *L) {
}
static int luaB_costatus ( lua_State * L ) {
lua_State * co = getco ( L ) ;
if ( L = = co ) lua_pushliteral ( L , " running " ) ;
# define COS_RUN 0
# define COS_DEAD 1
# define COS_YIELD 2
# define COS_NORM 3
static const char * statname [ ] = { " running " , " dead " , " suspended " , " normal " } ;
static int auxstatus ( lua_State * L , lua_State * co ) {
if ( L = = co ) return COS_RUN ;
else {
switch ( lua_status ( co ) ) {
case LUA_YIELD :
lua_pushliteral ( L , " suspended " ) ;
break ;
return COS_YIELD ;
case LUA_OK : {
lua_Debug ar ;
if ( lua_getstack ( co , 0 , & ar ) > 0 ) /* does it have frames? */
lua_pushliteral ( L , " normal " ) ; /* it is running */
if ( lua_getstack ( co , 0 , & ar ) ) /* does it have frames? */
return COS_NORM ; /* it is running */
else if ( lua_gettop ( co ) = = 0 )
lua_pushliteral ( L , " dead " ) ;
return COS_DEAD ;
else
lua_pushliteral ( L , " suspended " ) ; /* initial state */
break ;
return COS_YIELD ; /* initial state */
}
default : /* some error occurred */
lua_pushliteral ( L , " dead " ) ;
break ;
return COS_DEAD ;
}
}
}
static int luaB_costatus ( lua_State * L ) {
lua_State * co = getco ( L ) ;
lua_pushstring ( L , statname [ auxstatus ( L , co ) ] ) ;
return 1 ;
}
@ -147,6 +158,28 @@ static int luaB_corunning (lua_State *L) {
}
static int luaB_kill ( lua_State * L ) {
lua_State * co = getco ( L ) ;
int status = auxstatus ( L , co ) ;
switch ( status ) {
case COS_DEAD : case COS_YIELD : {
status = lua_resetthread ( co ) ;
if ( status = = LUA_OK ) {
lua_pushboolean ( L , 1 ) ;
return 1 ;
}
else {
lua_pushboolean ( L , 0 ) ;
lua_xmove ( co , L , 1 ) ; /* copy error message */
return 2 ;
}
}
default : /* normal or running coroutine */
return luaL_error ( L , " cannot kill a %s coroutine " , statname [ status ] ) ;
}
}
static const luaL_Reg co_funcs [ ] = {
{ " create " , luaB_cocreate } ,
{ " resume " , luaB_coresume } ,
@ -155,6 +188,7 @@ static const luaL_Reg co_funcs[] = {
{ " wrap " , luaB_cowrap } ,
{ " yield " , luaB_yield } ,
{ " isyieldable " , luaB_yieldable } ,
{ " kill " , luaB_kill } ,
{ NULL , NULL }
} ;