Skip to content
This repository was archived by the owner on Nov 1, 2023. It is now read-only.

Commit 7482700

Browse files
authored
Use elsa for debuggable_module::loader (#2703)
1 parent 5bf0c21 commit 7482700

File tree

3 files changed

+41
-85
lines changed

3 files changed

+41
-85
lines changed

src/agent/Cargo.lock

Lines changed: 24 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/agent/debuggable-module/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ license = "MIT"
66

77
[dependencies]
88
anyhow = "1.0"
9+
elsa = "1.7.0"
910
gimli = "0.26.2"
1011
goblin = "0.6.0"
1112
iced-x86 = "1.17"
Lines changed: 16 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,38 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

4-
use std::collections::HashMap;
5-
use std::sync::Mutex;
6-
74
use anyhow::Result;
8-
use thiserror::Error;
95

106
use crate::path::FilePath;
117

12-
#[derive(Clone, Copy)]
13-
struct Leaked(&'static [u8]);
14-
15-
impl Leaked {
16-
pub fn into_raw(self) -> *mut [u8] {
17-
self.0 as *const _ as *mut _
18-
}
8+
pub struct Loader {
9+
loaded: elsa::sync::FrozenMap<FilePath, Box<[u8]>>,
1910
}
2011

21-
impl From<Vec<u8>> for Leaked {
22-
fn from(data: Vec<u8>) -> Self {
23-
let data = Box::leak(data.into_boxed_slice());
24-
Leaked(data)
12+
impl Default for Loader {
13+
fn default() -> Self {
14+
Self {
15+
// sync version doesn't have a Default impl
16+
loaded: elsa::sync::FrozenMap::new(),
17+
}
2518
}
2619
}
2720

28-
#[derive(Default)]
29-
pub struct Loader {
30-
loaded: Mutex<HashMap<FilePath, Leaked>>,
31-
}
32-
3321
impl Loader {
3422
pub fn new() -> Self {
3523
Self::default()
3624
}
3725

3826
pub fn load(&self, path: &FilePath) -> Result<&[u8]> {
39-
if let Some(data) = self.get(path)? {
40-
Ok(data)
41-
} else {
42-
self.load_new(path)
43-
}
44-
}
45-
46-
fn load_new(&self, path: &FilePath) -> Result<&[u8]> {
47-
let mut loaded = self.loaded.lock().map_err(|_| LoaderError::PoisonedMutex)?;
48-
let data = std::fs::read(path)?;
49-
let leaked = Leaked::from(data);
50-
loaded.insert(path.clone(), leaked);
27+
// Note: if we ever have this callable in parallel from
28+
// multiple threads, we should use some kind of
29+
// lock to prevent loading the same file multiple times.
5130

52-
Ok(leaked.0)
53-
}
54-
55-
pub fn get(&self, path: &FilePath) -> Result<Option<&[u8]>> {
56-
let loaded = self.loaded.lock().map_err(|_| LoaderError::PoisonedMutex)?;
57-
58-
let data = loaded.get(path).map(|l| l.0);
59-
60-
Ok(data)
61-
}
62-
}
63-
64-
impl Drop for Loader {
65-
fn drop(&mut self) {
66-
if let Ok(mut loaded) = self.loaded.lock() {
67-
for (_, leaked) in loaded.drain() {
68-
unsafe {
69-
let raw = leaked.into_raw();
70-
let owned = Box::from_raw(raw);
71-
drop(owned);
72-
}
73-
}
74-
75-
debug_assert!(loaded.is_empty());
31+
if let Some(data) = self.loaded.get(path) {
32+
return Ok(data);
7633
}
77-
}
78-
}
7934

80-
#[derive(Error, Debug)]
81-
pub enum LoaderError {
82-
#[error("internal mutex poisoned")]
83-
PoisonedMutex,
35+
let data: Box<[u8]> = std::fs::read(path)?.into();
36+
Ok(self.loaded.insert(path.clone(), data))
37+
}
8438
}

0 commit comments

Comments
 (0)