Skip to content

Commit b55119f

Browse files
Review
1 parent 83035b0 commit b55119f

File tree

8 files changed

+54
-62
lines changed

8 files changed

+54
-62
lines changed

desktop/src/app.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ impl App {
316316
}
317317
DesktopFrontendMessage::PersistenceLoadDocuments => {
318318
// Open all documents in persisted tab order, then select the current one
319-
for (id, document) in self.persistent_data.all_documents() {
319+
for (id, document) in self.persistent_data.documents() {
320320
responses.push(DesktopWrapperMessage::LoadDocument {
321321
id,
322322
document,

desktop/src/cef.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ use crate::wrapper::{WgpuContext, deserialize_editor_message};
2727

2828
mod consts;
2929
mod context;
30-
mod dirs;
3130
mod input;
3231
mod internal;
3332
mod ipc;

desktop/src/cef/context/builder.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ use cef::{
44
App, BrowserSettings, CefString, Client, DictionaryValue, ImplCommandLine, ImplRequestContext, LogSeverity, RequestContextSettings, SchemeHandlerFactory, Settings, WindowInfo, api_hash,
55
browser_host_create_browser_sync, execute_process,
66
};
7-
use std::path::{Path, PathBuf};
7+
use std::path::Path;
88

99
use super::CefContext;
1010
use super::singlethreaded::SingleThreadedCefContext;
1111
use crate::cef::CefEventHandler;
1212
use crate::cef::consts::{RESOURCE_DOMAIN, RESOURCE_SCHEME};
13-
use crate::cef::dirs::{create_instance_dir, delete_instance_dirs};
1413
use crate::cef::input::InputState;
1514
use crate::cef::internal::{BrowserProcessAppImpl, BrowserProcessClientImpl, RenderProcessAppImpl, SchemeHandlerFactoryImpl};
15+
use crate::dirs::TempDir;
1616

1717
pub(crate) struct CefContextBuilder<H: CefEventHandler> {
1818
pub(crate) args: Args,
@@ -118,14 +118,13 @@ impl<H: CefEventHandler> CefContextBuilder<H> {
118118

119119
#[cfg(not(target_os = "macos"))]
120120
pub(crate) fn initialize(self, event_handler: H, disable_gpu_acceleration: bool) -> Result<impl CefContext, InitError> {
121-
delete_instance_dirs();
122-
let instance_dir = create_instance_dir();
121+
let instance_dir = TempDir::new().expect("Failed to create temporary directory for CEF instance");
123122

124123
let settings = Settings {
125124
multi_threaded_message_loop: 1,
126125
#[cfg(target_os = "linux")]
127126
no_sandbox: 1,
128-
..Self::common_settings(&instance_dir)
127+
..Self::common_settings(instance_dir.as_ref())
129128
};
130129

131130
self.initialize_inner(&event_handler, settings)?;
@@ -157,7 +156,7 @@ impl<H: CefEventHandler> CefContextBuilder<H> {
157156
}
158157
}
159158

160-
fn create_browser<H: CefEventHandler>(event_handler: H, instance_dir: PathBuf, disable_gpu_acceleration: bool) -> Result<SingleThreadedCefContext, InitError> {
159+
fn create_browser<H: CefEventHandler>(event_handler: H, instance_dir: TempDir, disable_gpu_acceleration: bool) -> Result<SingleThreadedCefContext, InitError> {
161160
let mut client = Client::new(BrowserProcessClientImpl::new(&event_handler));
162161

163162
#[cfg(feature = "accelerated_paint")]
@@ -211,7 +210,7 @@ fn create_browser<H: CefEventHandler>(event_handler: H, instance_dir: PathBuf, d
211210
event_handler: Box::new(event_handler),
212211
browser,
213212
input_state: InputState::default(),
214-
instance_dir,
213+
_instance_dir: instance_dir,
215214
})
216215
} else {
217216
tracing::error!("Failed to create browser");

desktop/src/cef/context/multithreaded.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,12 @@ impl CefContext for MultiThreadedCefContextProxy {
5454
impl Drop for MultiThreadedCefContextProxy {
5555
fn drop(&mut self) {
5656
// Force dropping underlying context on the UI thread
57-
run_on_ui_thread(move || drop(CONTEXT.take()));
57+
let (sync_drop_tx, sync_drop_rx) = std::sync::mpsc::channel();
58+
run_on_ui_thread(move || {
59+
drop(CONTEXT.take());
60+
sync_drop_tx.send(()).unwrap();
61+
});
62+
sync_drop_rx.recv().unwrap();
5863
}
5964
}
6065

desktop/src/cef/context/singlethreaded.rs

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ use winit::event::WindowEvent;
44
use crate::cef::input::InputState;
55
use crate::cef::ipc::{MessageType, SendMessage};
66
use crate::cef::{CefEventHandler, input};
7+
use crate::dirs::TempDir;
78

89
use super::CefContext;
910

1011
pub(super) struct SingleThreadedCefContext {
1112
pub(super) event_handler: Box<dyn CefEventHandler>,
1213
pub(super) browser: Browser,
1314
pub(super) input_state: InputState,
14-
pub(super) instance_dir: std::path::PathBuf,
15+
pub(super) _instance_dir: TempDir,
1516
}
1617

1718
impl CefContext for SingleThreadedCefContext {
@@ -46,19 +47,6 @@ impl Drop for SingleThreadedCefContext {
4647
// CEF wants us to close the browser before shutting down, otherwise it may run longer that necessary.
4748
self.browser.host().unwrap().close_browser(1);
4849
cef::shutdown();
49-
50-
// Sometimes some CEF processes still linger at this point and hold file handles to the cache directory.
51-
// To mitigate this, we try to remove the directory multiple times with some delay.
52-
// TODO: find a better solution if possible.
53-
for _ in 0..30 {
54-
match std::fs::remove_dir_all(&self.instance_dir) {
55-
Ok(_) => break,
56-
Err(e) => {
57-
tracing::warn!("Failed to remove CEF cache directory, retrying...: {e}");
58-
std::thread::sleep(std::time::Duration::from_millis(100));
59-
}
60-
}
61-
}
6250
}
6351
}
6452

@@ -68,7 +56,6 @@ impl SendMessage for SingleThreadedCefContext {
6856
tracing::error!("Main frame is not available, cannot send message");
6957
return;
7058
};
71-
7259
frame.send_message(message_type, message);
7360
}
7461
}

desktop/src/cef/dirs.rs

Lines changed: 0 additions & 24 deletions
This file was deleted.

desktop/src/dirs.rs

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
use std::fs::create_dir_all;
2-
use std::path::PathBuf;
1+
use std::fs;
2+
use std::io;
3+
use std::path::{Component, Path, PathBuf};
34

45
use crate::consts::{APP_DIRECTORY_NAME, APP_DOCUMENTS_DIRECTORY_NAME};
56

67
pub(crate) fn ensure_dir_exists(path: &PathBuf) {
78
if !path.exists() {
8-
create_dir_all(path).unwrap_or_else(|_| panic!("Failed to create directory at {path:?}"));
9+
fs::create_dir_all(path).unwrap_or_else(|_| panic!("Failed to create directory at {path:?}"));
910
}
1011
}
1112

@@ -20,3 +21,37 @@ pub(crate) fn app_autosave_documents_dir() -> PathBuf {
2021
ensure_dir_exists(&path);
2122
path
2223
}
24+
25+
/// Temporary directory that is automatically deleted when dropped.
26+
pub struct TempDir {
27+
path: PathBuf,
28+
}
29+
30+
impl TempDir {
31+
pub fn new() -> io::Result<Self> {
32+
Self::new_with_parent(dirs::cache_dir().unwrap_or_else(std::env::temp_dir))
33+
}
34+
35+
pub fn new_with_parent(parent: impl AsRef<Path>) -> io::Result<Self> {
36+
let random_suffix: String = (0..32).map(|_| format!("{:x}", rand::random::<u8>() % 16)).collect();
37+
let name = format!("{}_{}_{}", APP_DIRECTORY_NAME, std::process::id(), random_suffix);
38+
let path = parent.as_ref().join(name);
39+
fs::create_dir_all(&path)?;
40+
Ok(Self { path })
41+
}
42+
}
43+
44+
impl Drop for TempDir {
45+
fn drop(&mut self) {
46+
let result = fs::remove_dir_all(&self.path);
47+
if let Err(e) = result {
48+
tracing::error!("Failed to remove temporary directory at {:?}: {}", self.path, e);
49+
}
50+
}
51+
}
52+
53+
impl AsRef<Path> for TempDir {
54+
fn as_ref(&self) -> &Path {
55+
&self.path
56+
}
57+
}

desktop/src/persist.rs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ impl PersistentData {
5555
}
5656
}
5757

58-
pub(crate) fn all_documents(&self) -> Vec<(DocumentId, Document)> {
58+
pub(crate) fn documents(&self) -> Vec<(DocumentId, Document)> {
5959
self.documents.iter().filter_map(|doc| Some((doc.id, self.read_document(&doc.id)?))).collect()
6060
}
6161

@@ -132,7 +132,6 @@ impl PersistentData {
132132
*self = loaded;
133133

134134
self.garbage_collect_document_files();
135-
Self::delete_old_cef_browser_directory();
136135
}
137136

138137
// Remove orphaned document content files that have no corresponding entry in the persisted state
@@ -159,14 +158,6 @@ impl PersistentData {
159158
}
160159
}
161160

162-
// TODO: Eventually remove this cleanup code for the old "browser" CEF directory (renamed to "cef")
163-
fn delete_old_cef_browser_directory() {
164-
let old_browser_dir = crate::dirs::app_data_dir().join("browser");
165-
if old_browser_dir.is_dir() {
166-
let _ = std::fs::remove_dir_all(&old_browser_dir);
167-
}
168-
}
169-
170161
fn state_file_path() -> std::path::PathBuf {
171162
let mut path = crate::dirs::app_data_dir();
172163
path.push(crate::consts::APP_STATE_FILE_NAME);

0 commit comments

Comments
 (0)