@@ -30,14 +30,14 @@ use {
30
30
/// Status of a Lua thread (coroutine).
31
31
#[ derive( Debug , Copy , Clone , Eq , PartialEq ) ]
32
32
pub enum ThreadStatus {
33
- /// The thread was just created, or is suspended because it has called `coroutine.yield` .
33
+ /// The thread was just created or is suspended (yielded) .
34
34
///
35
35
/// If a thread is in this state, it can be resumed by calling [`Thread::resume`].
36
- ///
37
- /// [`Thread::resume`]: crate::Thread::resume
38
36
Resumable ,
39
- /// Either the thread has finished executing, or the thread is currently running.
40
- Unresumable ,
37
+ /// The thread is currently running.
38
+ Running ,
39
+ /// The thread has finished executing.
40
+ Finished ,
41
41
/// The thread has raised a Lua error during execution.
42
42
Error ,
43
43
}
@@ -108,7 +108,7 @@ impl Thread {
108
108
///
109
109
/// // The coroutine has now returned, so `resume` will fail
110
110
/// match thread.resume::<_, u32>(()) {
111
- /// Err(Error::CoroutineInactive ) => {},
111
+ /// Err(Error::CoroutineUnresumable ) => {},
112
112
/// unexpected => panic!("unexpected result {:?}", unexpected),
113
113
/// }
114
114
/// # Ok(())
@@ -120,9 +120,8 @@ impl Thread {
120
120
R : FromLuaMulti ,
121
121
{
122
122
let lua = self . 0 . lua . lock ( ) ;
123
-
124
- if unsafe { self . status_unprotected ( ) } != ThreadStatus :: Resumable {
125
- return Err ( Error :: CoroutineInactive ) ;
123
+ if self . status_inner ( & lua) != ThreadStatus :: Resumable {
124
+ return Err ( Error :: CoroutineUnresumable ) ;
126
125
}
127
126
128
127
let state = lua. state ( ) ;
@@ -170,25 +169,23 @@ impl Thread {
170
169
171
170
/// Gets the status of the thread.
172
171
pub fn status ( & self ) -> ThreadStatus {
173
- let _guard = self . 0 . lua . lock ( ) ;
174
- unsafe { self . status_unprotected ( ) }
172
+ self . status_inner ( & self . 0 . lua . lock ( ) )
175
173
}
176
174
177
- /// Gets the status of the thread without locking the Lua state .
178
- pub ( crate ) unsafe fn status_unprotected ( & self ) -> ThreadStatus {
175
+ /// Gets the status of the thread (internal implementation) .
176
+ pub ( crate ) fn status_inner ( & self , lua : & RawLua ) -> ThreadStatus {
179
177
let thread_state = self . state ( ) ;
180
- // FIXME: skip double lock
181
- if thread_state == self . 0 . lua . lock ( ) . state ( ) {
182
- // The coroutine is currently running
183
- return ThreadStatus :: Unresumable ;
178
+ if thread_state == lua. state ( ) {
179
+ // The thread is currently running
180
+ return ThreadStatus :: Running ;
184
181
}
185
- let status = ffi:: lua_status ( thread_state) ;
182
+ let status = unsafe { ffi:: lua_status ( thread_state) } ;
186
183
if status != ffi:: LUA_OK && status != ffi:: LUA_YIELD {
187
184
ThreadStatus :: Error
188
- } else if status == ffi:: LUA_YIELD || ffi:: lua_gettop ( thread_state) > 0 {
185
+ } else if status == ffi:: LUA_YIELD || unsafe { ffi:: lua_gettop ( thread_state) > 0 } {
189
186
ThreadStatus :: Resumable
190
187
} else {
191
- ThreadStatus :: Unresumable
188
+ ThreadStatus :: Finished
192
189
}
193
190
}
194
191
@@ -226,10 +223,11 @@ impl Thread {
226
223
#[ cfg_attr( docsrs, doc( cfg( any( feature = "lua54" , feature = "luau" ) ) ) ) ]
227
224
pub fn reset ( & self , func : crate :: function:: Function ) -> Result < ( ) > {
228
225
let lua = self . 0 . lua . lock ( ) ;
229
- let thread_state = self . state ( ) ;
230
- if thread_state == lua. state ( ) {
226
+ if self . status_inner ( & lua) == ThreadStatus :: Running {
231
227
return Err ( Error :: runtime ( "cannot reset a running thread" ) ) ;
232
228
}
229
+
230
+ let thread_state = self . state ( ) ;
233
231
unsafe {
234
232
#[ cfg( all( feature = "lua54" , not( feature = "vendored" ) ) ) ]
235
233
let status = ffi:: lua_resetthread ( thread_state) ;
@@ -398,7 +396,7 @@ impl<R> Drop for AsyncThread<R> {
398
396
// For Lua 5.4 this also closes all pending to-be-closed variables
399
397
if !lua. recycle_thread ( & mut self . thread ) {
400
398
#[ cfg( feature = "lua54" ) ]
401
- if self . thread . status_unprotected ( ) == ThreadStatus :: Error {
399
+ if self . thread . status_inner ( & lua ) == ThreadStatus :: Error {
402
400
#[ cfg( not( feature = "vendored" ) ) ]
403
401
ffi:: lua_resetthread ( self . thread . state ( ) ) ;
404
402
#[ cfg( feature = "vendored" ) ]
@@ -416,13 +414,13 @@ impl<R: FromLuaMulti> Stream for AsyncThread<R> {
416
414
417
415
fn poll_next ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
418
416
let lua = self . thread . 0 . lua . lock ( ) ;
417
+ if self . thread . status_inner ( & lua) != ThreadStatus :: Resumable {
418
+ return Poll :: Ready ( None ) ;
419
+ }
420
+
419
421
let state = lua. state ( ) ;
420
422
let thread_state = self . thread . state ( ) ;
421
423
unsafe {
422
- if self . thread . status_unprotected ( ) != ThreadStatus :: Resumable {
423
- return Poll :: Ready ( None ) ;
424
- }
425
-
426
424
let _sg = StackGuard :: new ( state) ;
427
425
let _thread_sg = StackGuard :: with_top ( thread_state, 0 ) ;
428
426
let _wg = WakerGuard :: new ( & lua, cx. waker ( ) ) ;
@@ -454,13 +452,13 @@ impl<R: FromLuaMulti> Future for AsyncThread<R> {
454
452
455
453
fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
456
454
let lua = self . thread . 0 . lua . lock ( ) ;
455
+ if self . thread . status_inner ( & lua) != ThreadStatus :: Resumable {
456
+ return Poll :: Ready ( Err ( Error :: CoroutineUnresumable ) ) ;
457
+ }
458
+
457
459
let state = lua. state ( ) ;
458
460
let thread_state = self . thread . state ( ) ;
459
461
unsafe {
460
- if self . thread . status_unprotected ( ) != ThreadStatus :: Resumable {
461
- return Poll :: Ready ( Err ( Error :: CoroutineInactive ) ) ;
462
- }
463
-
464
462
let _sg = StackGuard :: new ( state) ;
465
463
let _thread_sg = StackGuard :: with_top ( thread_state, 0 ) ;
466
464
let _wg = WakerGuard :: new ( & lua, cx. waker ( ) ) ;
0 commit comments