Optimize use of tokio::select!: Use biased selection (#580)

as there is no need to randomize the first one to be polled.

For `cancel_on_user_sig_term` and `StreamReadable::fill_buf`, the
cancellation future should always to be polled first so that user would
feel responsive.

Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
Jiahao XU 2022-11-30 14:05:52 +11:00 committed by GitHub
parent af82f1021c
commit ff737730f4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 10 additions and 2 deletions

View file

@ -122,10 +122,12 @@ where
let option = self.handle.block_on(async {
if let Some(cancellation_future) = self.cancellation_future.as_mut() {
tokio::select! {
res = next_stream(&mut self.stream) => res,
biased;
res = cancellation_future => {
Err(res.err().unwrap_or_else(|| io::Error::from(DownloadError::UserAbort)))
},
res = next_stream(&mut self.stream) => res,
}
} else {
next_stream(&mut self.stream).await

View file

@ -20,11 +20,13 @@ pub async fn cancel_on_user_sig_term<T>(
ignore_signals()?;
tokio::select! {
res = handle => res,
biased;
res = wait_on_cancellation_signal() => {
res.map_err(BinstallError::Io)
.and(Err(BinstallError::UserAbort))
}
res = handle => res,
}
}
@ -59,6 +61,8 @@ async fn wait_on_cancellation_signal_inner() -> Result<(), io::Error> {
}
tokio::select! {
biased;
res = signal::ctrl_c() => res,
res = inner() => res,
}
@ -72,6 +76,8 @@ mod unix {
/// Same as [`wait_on_cancellation_signal`] but is only available on unix.
pub async fn wait_on_cancellation_signal_unix() -> Result<(), io::Error> {
tokio::select! {
biased;
res = wait_for_signal_unix(SignalKind::interrupt()) => res,
res = wait_for_signal_unix(SignalKind::hangup()) => res,
res = wait_for_signal_unix(SignalKind::terminate()) => res,