diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-10-25 17:05:28 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-10-25 17:05:28 -0300 |
| commit | 96e15b8501e5d8fc40c475cbac573f910ab5853b (patch) | |
| tree | 2c8efededa6849704f0db3075d0cbe0efaa40b2d /lbaselib.c | |
| parent | 0fd91b1b087b478fffa36f96bc0f608d86627a4b (diff) | |
| download | lua-96e15b8501e5d8fc40c475cbac573f910ab5853b.tar.gz lua-96e15b8501e5d8fc40c475cbac573f910ab5853b.tar.bz2 lua-96e15b8501e5d8fc40c475cbac573f910ab5853b.zip | |
threads now are real Lua objects, subject to garbage collection
Diffstat (limited to 'lbaselib.c')
| -rw-r--r-- | lbaselib.c | 76 |
1 files changed, 42 insertions, 34 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lbaselib.c,v 1.99 2002/09/16 19:49:45 roberto Exp roberto $ | 2 | ** $Id: lbaselib.c,v 1.100 2002/10/22 19:41:08 roberto Exp roberto $ |
| 3 | ** Basic library | 3 | ** Basic library |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -362,6 +362,9 @@ static int luaB_tostring (lua_State *L) { | |||
| 362 | case LUA_TLIGHTUSERDATA: | 362 | case LUA_TLIGHTUSERDATA: |
| 363 | sprintf(buff, "userdata: %p", lua_touserdata(L, 1)); | 363 | sprintf(buff, "userdata: %p", lua_touserdata(L, 1)); |
| 364 | break; | 364 | break; |
| 365 | case LUA_TTHREAD: | ||
| 366 | sprintf(buff, "thread: %p", (void *)lua_tothread(L, 1)); | ||
| 367 | break; | ||
| 365 | case LUA_TNIL: | 368 | case LUA_TNIL: |
| 366 | lua_pushliteral(L, "nil"); | 369 | lua_pushliteral(L, "nil"); |
| 367 | return 1; | 370 | return 1; |
| @@ -535,26 +538,40 @@ static const luaL_reg base_funcs[] = { | |||
| 535 | */ | 538 | */ |
| 536 | 539 | ||
| 537 | 540 | ||
| 538 | static int luaB_resume (lua_State *L) { | 541 | static int luaB_auxresume (lua_State *L, lua_State *co) { |
| 539 | lua_State *co = (lua_State *)lua_unboxpointer(L, lua_upvalueindex(1)); | ||
| 540 | int status; | 542 | int status; |
| 541 | lua_settop(L, 0); | 543 | int oldtop = lua_gettop(L); |
| 542 | status = lua_resume(L, co); | 544 | status = lua_resume(L, co); |
| 543 | if (status != 0) | 545 | return (status != 0) ? -1 : lua_gettop(L) - oldtop; |
| 544 | return lua_error(L); | ||
| 545 | return lua_gettop(L); | ||
| 546 | } | 546 | } |
| 547 | 547 | ||
| 548 | 548 | ||
| 549 | static int luaB_coresume (lua_State *L) { | ||
| 550 | lua_State *co = lua_tothread(L, 1); | ||
| 551 | int r; | ||
| 552 | luaL_arg_check(L, co, 1, "coroutine/thread expected"); | ||
| 553 | r = luaB_auxresume(L, co); | ||
| 554 | if (r < 0) { | ||
| 555 | lua_pushboolean(L, 0); | ||
| 556 | lua_insert(L, -2); | ||
| 557 | return 2; /* return false + error message */ | ||
| 558 | } | ||
| 559 | else { | ||
| 560 | lua_pushboolean(L, 1); | ||
| 561 | lua_insert(L, -(r + 1)); | ||
| 562 | return r + 1; /* return true + `resume' returns */ | ||
| 563 | } | ||
| 564 | } | ||
| 565 | |||
| 549 | 566 | ||
| 550 | static int gc_coroutine (lua_State *L) { | 567 | static int luaB_auxwrap (lua_State *L) { |
| 551 | lua_State *co = (lua_State *)lua_unboxpointer(L, 1); | 568 | int r = luaB_auxresume(L, lua_tothread(L, lua_upvalueindex(1))); |
| 552 | lua_closethread(L, co); | 569 | if (r < 0) lua_error(L); |
| 553 | return 0; | 570 | return r; |
| 554 | } | 571 | } |
| 555 | 572 | ||
| 556 | 573 | ||
| 557 | static int luaB_coroutine (lua_State *L) { | 574 | static int luaB_cocreate (lua_State *L) { |
| 558 | lua_State *NL; | 575 | lua_State *NL; |
| 559 | int ref; | 576 | int ref; |
| 560 | int i; | 577 | int i; |
| @@ -562,20 +579,21 @@ static int luaB_coroutine (lua_State *L) { | |||
| 562 | luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, | 579 | luaL_arg_check(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1, |
| 563 | "Lua function expected"); | 580 | "Lua function expected"); |
| 564 | NL = lua_newthread(L); | 581 | NL = lua_newthread(L); |
| 565 | if (NL == NULL) return luaL_error(L, "unable to create new thread"); | ||
| 566 | /* move function and arguments from L to NL */ | 582 | /* move function and arguments from L to NL */ |
| 567 | for (i=0; i<n; i++) { | 583 | for (i = 1; i <= n; i++) { |
| 584 | lua_pushvalue(L, i); | ||
| 568 | ref = lua_ref(L, 1); | 585 | ref = lua_ref(L, 1); |
| 569 | lua_getref(NL, ref); | 586 | lua_getref(NL, ref); |
| 570 | lua_insert(NL, 1); | ||
| 571 | lua_unref(L, ref); | 587 | lua_unref(L, ref); |
| 572 | } | 588 | } |
| 573 | lua_cobegin(NL, n-1); | 589 | lua_cobegin(NL, n-1); |
| 574 | lua_boxpointer(L, NL); | 590 | return 1; |
| 575 | lua_pushliteral(L, "Coroutine"); | 591 | } |
| 576 | lua_rawget(L, LUA_REGISTRYINDEX); | 592 | |
| 577 | lua_setmetatable(L, -2); | 593 | |
| 578 | lua_pushcclosure(L, luaB_resume, 1); | 594 | static int luaB_cowrap (lua_State *L) { |
| 595 | luaB_cocreate(L); | ||
| 596 | lua_pushcclosure(L, luaB_auxwrap, 1); | ||
| 579 | return 1; | 597 | return 1; |
| 580 | } | 598 | } |
| 581 | 599 | ||
| @@ -585,23 +603,13 @@ static int luaB_yield (lua_State *L) { | |||
| 585 | } | 603 | } |
| 586 | 604 | ||
| 587 | static const luaL_reg co_funcs[] = { | 605 | static const luaL_reg co_funcs[] = { |
| 588 | {"create", luaB_coroutine}, | 606 | {"create", luaB_cocreate}, |
| 607 | {"wrap", luaB_cowrap}, | ||
| 608 | {"resume", luaB_coresume}, | ||
| 589 | {"yield", luaB_yield}, | 609 | {"yield", luaB_yield}, |
| 590 | {NULL, NULL} | 610 | {NULL, NULL} |
| 591 | }; | 611 | }; |
| 592 | 612 | ||
| 593 | |||
| 594 | static void co_open (lua_State *L) { | ||
| 595 | luaL_opennamedlib(L, LUA_COLIBNAME, co_funcs, 0); | ||
| 596 | /* create metatable for coroutines */ | ||
| 597 | lua_pushliteral(L, "Coroutine"); | ||
| 598 | lua_newtable(L); | ||
| 599 | lua_pushliteral(L, "__gc"); | ||
| 600 | lua_pushcfunction(L, gc_coroutine); | ||
| 601 | lua_rawset(L, -3); | ||
| 602 | lua_rawset(L, LUA_REGISTRYINDEX); | ||
| 603 | } | ||
| 604 | |||
| 605 | /* }====================================================== */ | 613 | /* }====================================================== */ |
| 606 | 614 | ||
| 607 | 615 | ||
| @@ -625,7 +633,7 @@ static void base_open (lua_State *L) { | |||
| 625 | 633 | ||
| 626 | LUALIB_API int lua_baselibopen (lua_State *L) { | 634 | LUALIB_API int lua_baselibopen (lua_State *L) { |
| 627 | base_open(L); | 635 | base_open(L); |
| 628 | co_open(L); | 636 | luaL_opennamedlib(L, LUA_COLIBNAME, co_funcs, 0); |
| 629 | lua_newtable(L); | 637 | lua_newtable(L); |
| 630 | lua_setglobal(L, REQTAB); | 638 | lua_setglobal(L, REQTAB); |
| 631 | return 0; | 639 | return 0; |
