Optimize polling async functions (40% performance win)
This commit is contained in:
parent
0f5c68dcf8
commit
d5483988d2
52
src/lua.rs
52
src/lua.rs
|
@ -2773,31 +2773,33 @@ impl Lua {
|
||||||
unsafe extern "C" fn poll_future(state: *mut ffi::lua_State) -> c_int {
|
unsafe extern "C" fn poll_future(state: *mut ffi::lua_State) -> c_int {
|
||||||
let upvalue = get_userdata::<AsyncPollUpvalue>(state, ffi::lua_upvalueindex(1));
|
let upvalue = get_userdata::<AsyncPollUpvalue>(state, ffi::lua_upvalueindex(1));
|
||||||
let extra = (*upvalue).extra.get();
|
let extra = (*upvalue).extra.get();
|
||||||
callback_error_ext(state, extra, |nargs| {
|
callback_error_ext(state, extra, |_| {
|
||||||
if nargs < ffi::LUA_MINSTACK {
|
|
||||||
check_stack(state, ffi::LUA_MINSTACK - nargs)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
let lua: &Lua = mem::transmute((*extra).inner.assume_init_ref());
|
let lua: &Lua = mem::transmute((*extra).inner.assume_init_ref());
|
||||||
let _guard = StateGuard::new(&lua.0, state);
|
let _guard = StateGuard::new(&lua.0, state);
|
||||||
|
|
||||||
let fut = &mut (*upvalue).data;
|
let fut = &mut (*upvalue).data;
|
||||||
let mut ctx = Context::from_waker(lua.waker());
|
let mut ctx = Context::from_waker(lua.waker());
|
||||||
match fut.as_mut().poll(&mut ctx) {
|
match fut.as_mut().poll(&mut ctx) {
|
||||||
Poll::Pending => {
|
Poll::Pending => Ok(0),
|
||||||
check_stack(state, 1)?;
|
|
||||||
ffi::lua_pushboolean(state, 0);
|
|
||||||
Ok(1)
|
|
||||||
}
|
|
||||||
Poll::Ready(results) => {
|
Poll::Ready(results) => {
|
||||||
let results = results?;
|
let mut results = results?;
|
||||||
let nresults = results.len() as Integer;
|
let nresults = results.len();
|
||||||
let results = lua.create_sequence_from(results)?;
|
lua.push_value(Value::Integer(nresults as _))?;
|
||||||
check_stack(state, 3)?;
|
match nresults {
|
||||||
ffi::lua_pushboolean(state, 1);
|
0 => Ok(1),
|
||||||
lua.push_value(Value::Table(results))?;
|
1 | 2 => {
|
||||||
lua.push_value(Value::Integer(nresults))?;
|
// Fast path for 1 or 2 results without creating a table
|
||||||
Ok(3)
|
for r in results.drain_all() {
|
||||||
|
lua.push_value(r)?;
|
||||||
|
}
|
||||||
|
MultiValue::return_to_pool(results, lua);
|
||||||
|
Ok(nresults as c_int + 1)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
lua.push_value(Value::Table(lua.create_sequence_from(results)?))?;
|
||||||
|
Ok(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -2850,9 +2852,17 @@ impl Lua {
|
||||||
local poll = get_poll(...)
|
local poll = get_poll(...)
|
||||||
local pending, yield, unpack = pending, yield, unpack
|
local pending, yield, unpack = pending, yield, unpack
|
||||||
while true do
|
while true do
|
||||||
local ready, res, nres = poll()
|
local nres, res, res2 = poll()
|
||||||
if ready then
|
if nres ~= nil then
|
||||||
return unpack(res, nres)
|
if nres == 0 then
|
||||||
|
return
|
||||||
|
elseif nres == 1 then
|
||||||
|
return res
|
||||||
|
elseif nres == 2 then
|
||||||
|
return res, res2
|
||||||
|
else
|
||||||
|
return unpack(res, nres)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
yield(pending)
|
yield(pending)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue