提交 9c05c1c2 编写于 作者: A Alex Crichton

Fix a deadlock in channels, again.

This deadlock was caused when the channel was closed at just the right time, so
the extra `self.cnt.fetch_add` actually should have preserved the DISCONNECTED
state of the channel. by modifying this the channel entered a state such that
the port would never succeed in dropping.

This also moves the increment of self.steals until after the MAX_STEALS block.
The reason for this is that in 'fn recv()' the steals variable is decremented
immediately after the try_recv(), which could in theory set steals to -1 if it
was previously set to 0 in try_recv().

Closes #12340
上级 47c31831
......@@ -305,7 +305,6 @@ pub fn try_recv(&mut self) -> Result<T, Failure> {
// See the discussion in the stream implementation for why we we
// might decrement steals.
Some(data) => {
self.steals += 1;
if self.steals > MAX_STEALS {
match self.cnt.swap(0, atomics::SeqCst) {
DISCONNECTED => {
......@@ -314,11 +313,12 @@ pub fn try_recv(&mut self) -> Result<T, Failure> {
n => {
let m = cmp::min(n, self.steals);
self.steals -= m;
self.cnt.fetch_add(n - m, atomics::SeqCst);
self.bump(n - m);
}
}
assert!(self.steals >= 0);
}
self.steals += 1;
Ok(data)
}
......
......@@ -213,7 +213,6 @@ pub fn try_recv(&mut self) -> Result<T, Failure<T>> {
// down as much as possible (without going negative), and then
// adding back in whatever we couldn't factor into steals.
Some(data) => {
self.steals += 1;
if self.steals > MAX_STEALS {
match self.cnt.swap(0, atomics::SeqCst) {
DISCONNECTED => {
......@@ -222,11 +221,12 @@ pub fn try_recv(&mut self) -> Result<T, Failure<T>> {
n => {
let m = cmp::min(n, self.steals);
self.steals -= m;
self.cnt.fetch_add(n - m, atomics::SeqCst);
self.bump(n - m);
}
}
assert!(self.steals >= 0);
}
self.steals += 1;
match data {
Data(t) => Ok(t),
GoUp(up) => Err(Upgraded(up)),
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册