Make AsyncPollPending internal value as LightUserData

This commit is contained in:
Alex Orlenko 2021-05-02 12:06:32 +01:00
parent e8505b5239
commit 67bc0b1196
2 changed files with 12 additions and 28 deletions

View File

@ -95,7 +95,7 @@ pub enum GCMode {
} }
#[cfg(feature = "async")] #[cfg(feature = "async")]
pub(crate) struct AsyncPollPending; pub(crate) static ASYNC_POLL_PENDING: u8 = 0;
#[cfg(feature = "async")] #[cfg(feature = "async")]
pub(crate) static WAKER_REGISTRY_KEY: u8 = 0; pub(crate) static WAKER_REGISTRY_KEY: u8 = 0;
pub(crate) static EXTRA_REGISTRY_KEY: u8 = 0; pub(crate) static EXTRA_REGISTRY_KEY: u8 = 0;
@ -317,7 +317,6 @@ impl Lua {
{ {
init_gc_metatable_for::<AsyncCallback>(state, None)?; init_gc_metatable_for::<AsyncCallback>(state, None)?;
init_gc_metatable_for::<LocalBoxFuture<Result<MultiValue>>>(state, None)?; init_gc_metatable_for::<LocalBoxFuture<Result<MultiValue>>>(state, None)?;
init_gc_metatable_for::<AsyncPollPending>(state, None)?;
init_gc_metatable_for::<Waker>(state, None)?; init_gc_metatable_for::<Waker>(state, None)?;
} }
@ -1818,11 +1817,8 @@ impl Lua {
)) ))
})?, })?,
)?; )?;
env.set("pending", unsafe { env.set("pending", {
let _sg = StackGuard::new(self.state); LightUserData(&ASYNC_POLL_PENDING as *const u8 as *mut c_void)
check_stack(self.state, 3)?;
push_gc_userdata(self.state, AsyncPollPending)?;
self.pop_value()
})?; })?;
// We set `poll` variable in the env table to be able to destroy upvalues // We set `poll` variable in the env table to be able to destroy upvalues

View File

@ -11,8 +11,8 @@ use crate::value::{FromLuaMulti, MultiValue, ToLuaMulti};
use { use {
crate::{ crate::{
error::ExternalError, error::ExternalError,
lua::{AsyncPollPending, Lua, WAKER_REGISTRY_KEY}, lua::{ASYNC_POLL_PENDING, WAKER_REGISTRY_KEY},
util::{get_gc_userdata, push_gc_userdata}, util::push_gc_userdata,
value::Value, value::Value,
}, },
futures_core::{future::Future, stream::Stream}, futures_core::{future::Future, stream::Stream},
@ -255,7 +255,7 @@ where
self.thread.resume(())? self.thread.resume(())?
}; };
if is_poll_pending(lua, &ret) { if is_poll_pending(&ret) {
return Poll::Pending; return Poll::Pending;
} }
@ -286,7 +286,7 @@ where
self.thread.resume(())? self.thread.resume(())?
}; };
if is_poll_pending(lua, &ret) { if is_poll_pending(&ret) {
return Poll::Pending; return Poll::Pending;
} }
@ -301,25 +301,13 @@ where
} }
#[cfg(feature = "async")] #[cfg(feature = "async")]
fn is_poll_pending(lua: &Lua, val: &MultiValue) -> bool { fn is_poll_pending(val: &MultiValue) -> bool {
if val.len() != 1 { match val.iter().enumerate().last() {
return false; Some((1, Value::LightUserData(ud))) => {
ud.0 == &ASYNC_POLL_PENDING as *const u8 as *mut c_void
} }
_ => false,
if let Some(Value::UserData(ud)) = val.iter().next() {
unsafe {
let _sg = StackGuard::new(lua.state);
assert_stack(lua.state, 3);
lua.push_ref(&ud.0);
let is_pending = !get_gc_userdata::<AsyncPollPending>(lua.state, -1).is_null();
ffi::lua_pop(lua.state, 1);
return is_pending;
} }
}
false
} }
#[cfg(feature = "async")] #[cfg(feature = "async")]