Skip to content

Commit 3d3f9e3

Browse files
ids1024cmeissl
authored andcommitted
wayland/image-copy: Don't use mem::forget in Frame
Unsurprisingly, this was causing leaks. Just adding a `bool` field seems like the simplest way to handle this, while still being able to deref, etc.
1 parent 2608eb1 commit 3d3f9e3

File tree

1 file changed

+33
-22
lines changed
  • src/wayland/image_copy_capture

1 file changed

+33
-22
lines changed

src/wayland/image_copy_capture/mod.rs

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -665,18 +665,21 @@ impl FrameRef {
665665
///
666666
/// If the frame is dropped without calling either method, it will automatically fail.
667667
#[derive(Debug)]
668-
pub struct Frame(FrameRef);
668+
pub struct Frame {
669+
frame: FrameRef,
670+
completed: bool,
671+
}
669672

670673
impl ops::Deref for Frame {
671674
type Target = FrameRef;
672675
fn deref(&self) -> &FrameRef {
673-
&self.0
676+
&self.frame
674677
}
675678
}
676679

677680
impl PartialEq<FrameRef> for Frame {
678681
fn eq(&self, other: &FrameRef) -> bool {
679-
self.0 == *other
682+
self.frame == *other
680683
}
681684
}
682685

@@ -689,21 +692,21 @@ impl Frame {
689692
/// * `damage` - Optional damage regions, or `None` for full damage
690693
/// * `presented` - The presentation timestamp
691694
pub fn success(
692-
self,
695+
mut self,
693696
transform: impl Into<Transform>,
694697
damage: impl Into<Option<Vec<Rectangle<i32, BufferCoords>>>>,
695698
presented: impl Into<Duration>,
696699
) {
697700
{
698-
let inner = self.0.inner.lock().unwrap();
701+
let inner = self.frame.inner.lock().unwrap();
699702
if !inner.capture_requested || inner.failed.is_some() {
700703
return;
701704
}
702705
}
703706

704-
self.0.obj.transform(transform.into().into());
707+
self.frame.obj.transform(transform.into().into());
705708
for damage in damage.into().into_iter().flatten() {
706-
self.0
709+
self.frame
707710
.obj
708711
.damage(damage.loc.x, damage.loc.y, damage.size.w, damage.size.h);
709712
}
@@ -712,31 +715,33 @@ impl Frame {
712715
let tv_sec_hi = (time.as_secs() >> 32) as u32;
713716
let tv_sec_lo = (time.as_secs() & 0xFFFFFFFF) as u32;
714717
let tv_nsec = time.subsec_nanos();
715-
self.0.obj.presentation_time(tv_sec_hi, tv_sec_lo, tv_nsec);
718+
self.frame.obj.presentation_time(tv_sec_hi, tv_sec_lo, tv_nsec);
716719

717-
self.0.inner.lock().unwrap().ready = true;
718-
self.0.obj.ready();
720+
self.frame.inner.lock().unwrap().ready = true;
721+
self.frame.obj.ready();
719722

720723
// Prevent drop from sending fail
721-
std::mem::forget(self);
724+
self.completed = true;
722725
}
723726

724727
/// Signal failed capture.
725-
pub fn fail(self, reason: FailureReason) {
726-
self.0.inner.lock().unwrap().fail(&self.0.obj, reason);
728+
pub fn fail(mut self, reason: FailureReason) {
729+
self.frame.inner.lock().unwrap().fail(&self.frame.obj, reason);
727730
// Prevent drop from sending fail again
728-
std::mem::forget(self);
731+
self.completed = true;
729732
}
730733
}
731734

732735
impl Drop for Frame {
733736
fn drop(&mut self) {
734-
// If success() or fail() wasn't called, send Unknown failure
735-
self.0
736-
.inner
737-
.lock()
738-
.unwrap()
739-
.fail(&self.0.obj, FailureReason::Unknown);
737+
if !self.completed {
738+
// If success() or fail() wasn't called, send Unknown failure
739+
self.frame
740+
.inner
741+
.lock()
742+
.unwrap()
743+
.fail(&self.frame.obj, FailureReason::Unknown);
744+
}
740745
}
741746
}
742747

@@ -1289,7 +1294,10 @@ where
12891294
if session_inner.active_frames.iter().any(|f| f == &frame_ref) {
12901295
drop(session_inner);
12911296
let session_ref = session.clone();
1292-
let frame = Frame(frame_ref);
1297+
let frame = Frame {
1298+
frame: frame_ref,
1299+
completed: false,
1300+
};
12931301
state.frame(&session_ref, frame);
12941302
return;
12951303
}
@@ -1301,7 +1309,10 @@ where
13011309
if session_inner.active_frames.iter().any(|f| f == &frame_ref) {
13021310
drop(session_inner);
13031311
let session_ref = session.clone();
1304-
let frame = Frame(frame_ref);
1312+
let frame = Frame {
1313+
frame: frame_ref,
1314+
completed: false,
1315+
};
13051316
state.cursor_frame(&session_ref, frame);
13061317
return;
13071318
}

0 commit comments

Comments
 (0)