Skip to content

Commit

Permalink
fix: memory leak in Image (#934)
Browse files Browse the repository at this point in the history
There 2 leak points in the `Image` class.

1. The `Env::create_reference` was wrong in NAPI-RS, related pr: napi-rs/napi-rs#2347, change to the `Ref::new` can resolve it.
2. The `PromiseRaw::catch` callback was leaked, it cause the whole `Image` objects not be GCed, it was fixed in napi-rs/napi-rs#2348
  • Loading branch information
Brooooooklyn authored Nov 7, 2024
1 parent 8aed65e commit cfc4da5
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 6 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ base64-simd = "0.8"
cssparser = "0.29"
infer = "0.16"
libavif = { version = "0.14", default-features = false, features = ["codec-aom"] }
napi = { version = "3.0.0-alpha.19", default-features = false, features = ["napi3", "serde-json"] }
napi-derive = { version = "3.0.0-alpha.17", default-features = false }
napi = { version = "3.0.0-alpha.20", default-features = false, features = ["napi3", "serde-json"] }
napi-derive = { version = "3.0.0-alpha.18", default-features = false }
nom = "7"
num_cpus = "1"
regex = "1"
Expand Down
8 changes: 6 additions & 2 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,12 @@ fn main() {
env::set_var("CXX", "clang-cl");
}
_ => {
env::set_var("CC", "clang");
env::set_var("CXX", "clang++");
if env::var("CC").is_err() {
env::set_var("CC", "clang");
}
if env::var("CXX").is_err() {
env::set_var("CXX", "clang++");
}
}
}

Expand Down
14 changes: 12 additions & 2 deletions src/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ impl ImageData {
}
}

#[napi]
#[napi(custom_finalize)]
pub struct Image {
pub(crate) bitmap: Option<Bitmap>,
pub(crate) complete: bool,
Expand All @@ -127,6 +127,15 @@ pub struct Image {
pub(crate) src: Option<Uint8Array>,
}

impl ObjectFinalize for Image {
fn finalize(self, env: Env) -> Result<()> {
if let Some(bitmap) = self.bitmap {
env.adjust_external_memory(-(bitmap.0.width as i64) * (bitmap.0.height as i64) * 4)?;
}
Ok(())
}
}

#[napi]
impl Image {
#[napi(constructor)]
Expand Down Expand Up @@ -239,7 +248,7 @@ impl Image {
height: self.height,
color_space: self.color_space,
data: Some(data),
this_ref: env.create_reference(&*this)?,
this_ref: Ref::new(&env, &*this)?,
};
let task_output = env.spawn(decoder)?;

Expand Down Expand Up @@ -442,6 +451,7 @@ impl Task for BitmapDecoder {
self_mut.src = self.data.take();
self_mut.is_svg = bitmap.is_svg;
self_mut.bitmap = Some(bitmap.data);
env.adjust_external_memory((output.width as i64) * (output.height as i64) * 4)?;
}
DecodeStatus::Empty => {}
DecodeStatus::InvalidSvg => {
Expand Down

0 comments on commit cfc4da5

Please sign in to comment.