Skip to content

Commit 01125b3

Browse files
committed
Implement Drop for FrameData
The types `Frame` and `FrameData` are mutually recursive, and the incidental linked lists that can be formed as a result can be long (at least in the order of thousands of elements). As a result, when a frame is deallocated, rust appears to recursively call `drop_in_place` down the list, causing stack overflows for long lists.
1 parent 6e2c022 commit 01125b3

File tree

1 file changed

+26
-0
lines changed

1 file changed

+26
-0
lines changed

src/source/buffered.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::cmp;
2+
use std::mem;
23
use std::sync::{Arc, Mutex};
34
use std::time::Duration;
45

@@ -66,6 +67,31 @@ where
6667
next: Mutex<Arc<Frame<I>>>,
6768
}
6869

70+
impl<I> Drop for FrameData<I>
71+
where
72+
I: Source,
73+
I::Item: Sample,
74+
{
75+
fn drop(&mut self) {
76+
loop {
77+
if let Ok(arc_next) = self.next.get_mut() {
78+
if let Some(next_ref) = Arc::get_mut(arc_next) {
79+
let next = mem::replace(next_ref, Frame::End);
80+
if let Frame::Data(next_data) = next {
81+
mem::replace(self, next_data);
82+
} else {
83+
break;
84+
}
85+
} else {
86+
break;
87+
}
88+
} else {
89+
break;
90+
}
91+
}
92+
}
93+
}
94+
6995
/// Builds a frame from the input iterator.
7096
fn extract<I>(mut input: I) -> Arc<Frame<I>>
7197
where

0 commit comments

Comments
 (0)