mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
51 lines
1.1 KiB
Rust
51 lines
1.1 KiB
Rust
use std::{mem, ops::Deref};
|
|
|
|
use futures::{FutureExt, future::BoxFuture};
|
|
use mlua::{UserData, UserDataMethods};
|
|
use tokio::sync::SemaphorePermit;
|
|
|
|
pub type PermitRef = mlua::UserDataRef<Permit>;
|
|
|
|
pub struct Permit {
|
|
inner: Option<SemaphorePermit<'static>>,
|
|
destruct: Option<BoxFuture<'static, ()>>,
|
|
}
|
|
|
|
impl Deref for Permit {
|
|
type Target = Option<SemaphorePermit<'static>>;
|
|
|
|
fn deref(&self) -> &Self::Target { &self.inner }
|
|
}
|
|
|
|
impl Permit {
|
|
pub fn new<F>(inner: SemaphorePermit<'static>, f: F) -> Self
|
|
where
|
|
F: Future<Output = ()> + 'static + Send,
|
|
{
|
|
Self { inner: Some(inner), destruct: Some(f.boxed()) }
|
|
}
|
|
|
|
fn dropping(&mut self) -> impl Future<Output = ()> + 'static {
|
|
let inner = self.inner.take();
|
|
let destruct = self.destruct.take();
|
|
|
|
async move {
|
|
if let Some(f) = destruct {
|
|
f.await;
|
|
}
|
|
if let Some(p) = inner {
|
|
mem::drop(p);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Drop for Permit {
|
|
fn drop(&mut self) { tokio::spawn(self.dropping()); }
|
|
}
|
|
|
|
impl UserData for Permit {
|
|
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
|
methods.add_async_method_once("drop", |_, mut me, ()| async move { Ok(me.dropping().await) });
|
|
}
|
|
}
|