Skip to content

Commit

Permalink
sorting memory leak in Draw
Browse files Browse the repository at this point in the history
  • Loading branch information
sminez committed Jun 14, 2024
1 parent dfaedf7 commit 36f7a1a
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 4 deletions.
7 changes: 5 additions & 2 deletions crates/penrose_ui/src/core/fontset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ impl Drop for Fontset {
// SAFETY: the Display we have a pointer to is freed by the parent draw
unsafe {
XftFontClose(self.dpy, self.primary.xfont);
for f in self.fallback.drain(0..) {
for f in self.fallback.drain(..) {
XftFontClose(self.dpy, f.xfont);
}
}
Expand Down Expand Up @@ -214,7 +214,10 @@ impl Font {
ext,
);

Ok(((*ext).xOff as u32, self.h))
let x_off = (*ext).xOff as u32;
std::alloc::dealloc(ext as *mut u8, layout);

Ok((x_off, self.h))
}
}

Expand Down
23 changes: 21 additions & 2 deletions crates/penrose_ui/src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use std::{
};
use tracing::{debug, info};
use x11::{
xft::{XftColor, XftColorAllocName, XftDrawCreate, XftDrawStringUtf8},
xft::{XftColor, XftColorAllocName, XftDraw, XftDrawCreate, XftDrawDestroy, XftDrawStringUtf8},
xlib::{
CapButt, Complex, CoordModeOrigin, Display, Drawable, False, JoinMiter, LineSolid, Window,
XCopyArea, XCreateGC, XCreatePixmap, XDefaultColormap, XDefaultDepth, XDefaultVisual,
Expand Down Expand Up @@ -419,6 +419,8 @@ impl<'a> Context<'a> {
) -> Result<(u32, u32)> {
// SAFETY:
// - the pointers for self.dpy and s.drawable are known to be non-null
// - we wrap the returned pointer in DropXftDraw to ensure that we correctly destroy
// the XftDraw we create here (see below)
let d = unsafe {
XftDrawCreate(
self.dpy,
Expand All @@ -428,6 +430,8 @@ impl<'a> Context<'a> {
)
};

let _drop_draw = DropXftDraw { ptr: d };

let (lpad, rpad) = (padding.0 as i32, padding.1);
let (mut x, y) = (lpad + self.dx, self.dy);
let (mut total_w, mut total_h) = (x as u32, 0);
Expand Down Expand Up @@ -461,7 +465,22 @@ impl<'a> Context<'a> {
total_h = max(total_h, chunk_h);
}

Ok((total_w + rpad, total_h))
return Ok((total_w + rpad, total_h));

// There are multiple error paths here where we need to make sure that we correctly destroy
// the XftDraw we created. Rather than complicate the error handling we use a Drop wrapper
// to ensure that we run XftDrawDestroy when the function returns.

struct DropXftDraw {
ptr: *mut XftDraw,
}

impl Drop for DropXftDraw {
fn drop(&mut self) {
// SAFETY: the pointer we have must be non-null
unsafe { XftDrawDestroy(self.ptr) };
}
}
}

/// Determine the width and height taken up by a given string in pixels.
Expand Down

0 comments on commit 36f7a1a

Please sign in to comment.