patch(cliprdr): avoid too much open
1. force sync local files when processing file list format data request 2. avoid construct file list each time pulling file lists from clipboard Signed-off-by: ClSlaid <cailue@bupt.edu.cn>
This commit is contained in:
parent
9976fc9723
commit
abe40c84b0
@ -64,7 +64,7 @@ trait SysClipboard: Send + Sync {
|
|||||||
fn stop(&self);
|
fn stop(&self);
|
||||||
|
|
||||||
fn set_file_list(&self, paths: &[PathBuf]) -> Result<(), CliprdrError>;
|
fn set_file_list(&self, paths: &[PathBuf]) -> Result<(), CliprdrError>;
|
||||||
fn get_file_list(&self) -> Result<Vec<LocalFile>, CliprdrError>;
|
fn get_file_list(&self) -> Vec<PathBuf>;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_sys_clipboard(ignore_path: &PathBuf) -> Result<Box<dyn SysClipboard>, CliprdrError> {
|
fn get_sys_clipboard(ignore_path: &PathBuf) -> Result<Box<dyn SysClipboard>, CliprdrError> {
|
||||||
@ -105,6 +105,7 @@ pub struct ClipboardContext {
|
|||||||
fuse_server: Arc<Mutex<FuseServer>>,
|
fuse_server: Arc<Mutex<FuseServer>>,
|
||||||
|
|
||||||
clipboard: Arc<dyn SysClipboard>,
|
clipboard: Arc<dyn SysClipboard>,
|
||||||
|
local_files: Mutex<Vec<LocalFile>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClipboardContext {
|
impl ClipboardContext {
|
||||||
@ -121,6 +122,7 @@ impl ClipboardContext {
|
|||||||
|
|
||||||
let clipboard = get_sys_clipboard(&fuse_mount_point)?;
|
let clipboard = get_sys_clipboard(&fuse_mount_point)?;
|
||||||
let clipboard = Arc::from(clipboard) as Arc<_>;
|
let clipboard = Arc::from(clipboard) as Arc<_>;
|
||||||
|
let local_files = Mutex::new(vec![]);
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
fuse_mount_point,
|
fuse_mount_point,
|
||||||
@ -128,6 +130,7 @@ impl ClipboardContext {
|
|||||||
fuse_tx,
|
fuse_tx,
|
||||||
fuse_handle: Mutex::new(None),
|
fuse_handle: Mutex::new(None),
|
||||||
clipboard,
|
clipboard,
|
||||||
|
local_files,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,13 +189,14 @@ impl ClipboardContext {
|
|||||||
conn_id: i32,
|
conn_id: i32,
|
||||||
request: FileContentsRequest,
|
request: FileContentsRequest,
|
||||||
) -> Result<(), CliprdrError> {
|
) -> Result<(), CliprdrError> {
|
||||||
let file_contents_req = match request {
|
let file_list = self.local_files.lock();
|
||||||
|
|
||||||
|
let file_contents_resp = match request {
|
||||||
FileContentsRequest::Size {
|
FileContentsRequest::Size {
|
||||||
stream_id,
|
stream_id,
|
||||||
file_idx,
|
file_idx,
|
||||||
} => {
|
} => {
|
||||||
log::debug!("file contents (size) requested from conn: {}", conn_id);
|
log::debug!("file contents (size) requested from conn: {}", conn_id);
|
||||||
let file_list = self.clipboard.get_file_list()?;
|
|
||||||
let Some(file) = file_list.get(file_idx) else {
|
let Some(file) = file_list.get(file_idx) else {
|
||||||
log::error!(
|
log::error!(
|
||||||
"invalid file index {} requested from conn: {}",
|
"invalid file index {} requested from conn: {}",
|
||||||
@ -235,7 +239,6 @@ impl ClipboardContext {
|
|||||||
length,
|
length,
|
||||||
conn_id
|
conn_id
|
||||||
);
|
);
|
||||||
let file_list = self.clipboard.get_file_list()?;
|
|
||||||
let Some(file) = file_list.get(file_idx) else {
|
let Some(file) = file_list.get(file_idx) else {
|
||||||
log::error!(
|
log::error!(
|
||||||
"invalid file index {} requested from conn: {}",
|
"invalid file index {} requested from conn: {}",
|
||||||
@ -307,7 +310,7 @@ impl ClipboardContext {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
send_data(conn_id, file_contents_req);
|
send_data(conn_id, file_contents_resp);
|
||||||
log::debug!("file contents sent to conn: {}", conn_id);
|
log::debug!("file contents sent to conn: {}", conn_id);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -327,6 +330,18 @@ impl ClipboardContext {
|
|||||||
self.fuse_handle.lock().is_none()
|
self.fuse_handle.lock().is_none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn sync_local_files(&self) -> Result<(), CliprdrError> {
|
||||||
|
let mut local_files = self.local_files.lock();
|
||||||
|
let clipboard_files = self.clipboard.get_file_list();
|
||||||
|
let local_file_list: Vec<PathBuf> = local_files.iter().map(|f| f.path.clone()).collect();
|
||||||
|
if local_file_list == clipboard_files {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
let new_files = construct_file_list(&clipboard_files)?;
|
||||||
|
*local_files = new_files;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn serve(&self, conn_id: i32, msg: ClipboardFile) -> Result<(), CliprdrError> {
|
pub fn serve(&self, conn_id: i32, msg: ClipboardFile) -> Result<(), CliprdrError> {
|
||||||
log::debug!("serve clipboard file from conn: {}", conn_id);
|
log::debug!("serve clipboard file from conn: {}", conn_id);
|
||||||
if self.is_stopped() {
|
if self.is_stopped() {
|
||||||
@ -496,9 +511,10 @@ impl ClipboardContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn send_file_list(&self, conn_id: i32) -> Result<(), CliprdrError> {
|
fn send_file_list(&self, conn_id: i32) -> Result<(), CliprdrError> {
|
||||||
let file_list = self.clipboard.get_file_list()?;
|
self.sync_local_files()?;
|
||||||
|
|
||||||
send_file_list(&file_list, conn_id)
|
let file_list = self.local_files.lock();
|
||||||
|
send_file_list(&*file_list, conn_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,10 +10,7 @@ use parking_lot::Mutex;
|
|||||||
use x11_clipboard::Clipboard;
|
use x11_clipboard::Clipboard;
|
||||||
use x11rb::protocol::xproto::Atom;
|
use x11rb::protocol::xproto::Atom;
|
||||||
|
|
||||||
use crate::{
|
use crate::{platform::linux::send_format_list, CliprdrError};
|
||||||
platform::linux::{construct_file_list, send_format_list},
|
|
||||||
CliprdrError,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{encode_path_to_uri, parse_plain_uri_list, SysClipboard};
|
use super::{encode_path_to_uri, parse_plain_uri_list, SysClipboard};
|
||||||
|
|
||||||
@ -159,14 +156,12 @@ impl SysClipboard for X11Clipboard {
|
|||||||
let mut former = self.former_file_list.lock();
|
let mut former = self.former_file_list.lock();
|
||||||
|
|
||||||
let filtered_st: BTreeSet<_> = filtered.iter().collect();
|
let filtered_st: BTreeSet<_> = filtered.iter().collect();
|
||||||
let former_st = former.iter().collect();
|
let former_st = former.iter().collect::<BTreeSet<_>>();
|
||||||
if filtered_st == former_st {
|
if filtered_st == former_st {
|
||||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// send update to server
|
|
||||||
log::debug!("clipboard updated: {:?}", filtered);
|
|
||||||
*former = filtered;
|
*former = filtered;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,8 +175,7 @@ impl SysClipboard for X11Clipboard {
|
|||||||
log::debug!("stop listening file related atoms on clipboard");
|
log::debug!("stop listening file related atoms on clipboard");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_file_list(&self) -> Result<Vec<super::LocalFile>, CliprdrError> {
|
fn get_file_list(&self) -> Vec<PathBuf> {
|
||||||
let paths = { self.former_file_list.lock().clone() };
|
self.former_file_list.lock().clone()
|
||||||
construct_file_list(&paths)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user