@@ -613,46 +613,11 @@ impl RawLua {
613613 self . create_thread ( func)
614614 }
615615
616- /// Resets thread (coroutine) and returns it to the pool for later use.
616+ /// Returns the thread to the pool for later use.
617617 #[ cfg( feature = "async" ) ]
618618 pub ( crate ) unsafe fn recycle_thread ( & self , thread : & mut Thread ) {
619- let thread_state = thread. 1 ;
620619 let extra = & mut * self . extra . get ( ) ;
621- if extra. thread_pool . len ( ) == extra. thread_pool . capacity ( ) {
622- #[ cfg( feature = "lua54" ) ]
623- if ffi:: lua_status ( thread_state) != ffi:: LUA_OK {
624- // Close all to-be-closed variables without returning thread to the pool
625- #[ cfg( not( feature = "vendored" ) ) ]
626- ffi:: lua_resetthread ( thread_state) ;
627- #[ cfg( feature = "vendored" ) ]
628- ffi:: lua_closethread ( thread_state, self . state ( ) ) ;
629- }
630- return ;
631- }
632-
633- let mut reset_ok = false ;
634- if ffi:: lua_status ( thread_state) == ffi:: LUA_OK {
635- if ffi:: lua_gettop ( thread_state) > 0 {
636- ffi:: lua_settop ( thread_state, 0 ) ;
637- }
638- reset_ok = true ;
639- }
640-
641- #[ cfg( feature = "lua54" ) ]
642- if !reset_ok {
643- #[ cfg( not( feature = "vendored" ) ) ]
644- let status = ffi:: lua_resetthread ( thread_state) ;
645- #[ cfg( feature = "vendored" ) ]
646- let status = ffi:: lua_closethread ( thread_state, self . state ( ) ) ;
647- reset_ok = status == ffi:: LUA_OK ;
648- }
649- #[ cfg( feature = "luau" ) ]
650- if !reset_ok {
651- ffi:: lua_resetthread ( thread_state) ;
652- reset_ok = true ;
653- }
654-
655- if reset_ok {
620+ if extra. thread_pool . len ( ) < extra. thread_pool . capacity ( ) {
656621 extra. thread_pool . push ( thread. 0 . index ) ;
657622 thread. 0 . drop = false ; // Prevent thread from being garbage collected
658623 }
@@ -1244,7 +1209,7 @@ impl RawLua {
12441209 let rawlua = ( * extra) . raw_lua ( ) ;
12451210
12461211 let func = & * ( * upvalue) . data ;
1247- let fut = func ( rawlua, nargs) ;
1212+ let fut = Some ( func ( rawlua, nargs) ) ;
12481213 let extra = XRc :: clone ( & ( * upvalue) . extra ) ;
12491214 let protect = !rawlua. unlikely_memory_error ( ) ;
12501215 push_internal_userdata ( state, AsyncPollUpvalue { data : fut, extra } , protect) ?;
@@ -1262,20 +1227,27 @@ impl RawLua {
12621227
12631228 unsafe extern "C-unwind" fn poll_future ( state : * mut ffi:: lua_State ) -> c_int {
12641229 let upvalue = get_userdata :: < AsyncPollUpvalue > ( state, ffi:: lua_upvalueindex ( 1 ) ) ;
1265- callback_error_ext ( state, ( * upvalue) . extra . get ( ) , true , |extra, _ | {
1230+ callback_error_ext ( state, ( * upvalue) . extra . get ( ) , true , |extra, nargs | {
12661231 // Lua ensures that `LUA_MINSTACK` stack spaces are available (after pushing arguments)
12671232 // The lock must be already held as the future is polled
12681233 let rawlua = ( * extra) . raw_lua ( ) ;
12691234
1235+ if nargs == 1 && ffi:: lua_tolightuserdata ( state, -1 ) == Lua :: poll_terminate ( ) . 0 {
1236+ // Destroy the future and terminate the Lua thread
1237+ ( * upvalue) . data . take ( ) ;
1238+ ffi:: lua_pushinteger ( state, 0 ) ;
1239+ return Ok ( 1 ) ;
1240+ }
1241+
12701242 let fut = & mut ( * upvalue) . data ;
12711243 let mut ctx = Context :: from_waker ( rawlua. waker ( ) ) ;
1272- match fut. as_mut ( ) . poll ( & mut ctx) {
1273- Poll :: Pending => {
1244+ match fut. as_mut ( ) . map ( |fut| fut . as_mut ( ) . poll ( & mut ctx) ) {
1245+ Some ( Poll :: Pending ) => {
12741246 ffi:: lua_pushnil ( state) ;
12751247 ffi:: lua_pushlightuserdata ( state, Lua :: poll_pending ( ) . 0 ) ;
12761248 Ok ( 2 )
12771249 }
1278- Poll :: Ready ( nresults) => {
1250+ Some ( Poll :: Ready ( nresults) ) => {
12791251 match nresults? {
12801252 nresults if nresults < 3 => {
12811253 // Fast path for up to 2 results without creating a table
@@ -1293,6 +1265,7 @@ impl RawLua {
12931265 }
12941266 }
12951267 }
1268+ None => Err ( Error :: CallbackDestructed ) ,
12961269 }
12971270 } )
12981271 }
@@ -1338,8 +1311,8 @@ impl RawLua {
13381311 lua. load (
13391312 r#"
13401313 local poll = get_poll(...)
1314+ local nres, res, res2 = poll()
13411315 while true do
1342- local nres, res, res2 = poll()
13431316 if nres ~= nil then
13441317 if nres == 0 then
13451318 return
@@ -1351,7 +1324,10 @@ impl RawLua {
13511324 return unpack(res, nres)
13521325 end
13531326 end
1354- yield(res) -- `res` is a "pending" value
1327+ -- `res` is a "pending" value
1328+ -- `yield` can return a signal to drop the future that we should propagate
1329+ -- to the poller
1330+ nres, res, res2 = poll(yield(res))
13551331 end
13561332 "# ,
13571333 )
0 commit comments