Skip to content

Commit fae1dc4

Browse files
committed
---
yaml --- r: 101888 b: refs/heads/master c: bea7862 h: refs/heads/master v: v3
1 parent 60c9d6b commit fae1dc4

File tree

3 files changed

+29
-8
lines changed

3 files changed

+29
-8
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 836ffb528883225e036e506b3a8f112d81e096ff
2+
refs/heads/master: bea7862d9470c33b7b3e21a552a991e3b948aa29
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 6e7f170fedd3c526a643c0b2d13863acd982be02
55
refs/heads/try: a97642026c18a624ff6ea01075dd9550f8ed07ff

trunk/src/libstd/comm/shared.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
/// module. You'll also note that the implementation of the shared and stream
1919
/// channels are quite similar, and this is no coincidence!
2020
21+
use cmp;
2122
use int;
2223
use iter::Iterator;
2324
use kinds::Send;
@@ -35,6 +36,9 @@ use mpsc = sync::mpsc_queue;
3536

3637
static DISCONNECTED: int = int::MIN;
3738
static FUDGE: int = 1024;
39+
#[cfg(test)]
40+
static MAX_STEALS: int = 5;
41+
#[cfg(not(test))]
3842
static MAX_STEALS: int = 1 << 20;
3943

4044
pub struct Packet<T> {
@@ -307,7 +311,11 @@ impl<T: Send> Packet<T> {
307311
DISCONNECTED => {
308312
self.cnt.store(DISCONNECTED, atomics::SeqCst);
309313
}
310-
n => { self.steals -= n; }
314+
n => {
315+
let m = cmp::min(n, self.steals);
316+
self.steals -= m;
317+
self.cnt.fetch_add(n - m, atomics::SeqCst);
318+
}
311319
}
312320
assert!(self.steals >= 0);
313321
}

trunk/src/libstd/comm/stream.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
/// High level implementation details can be found in the comment of the parent
1818
/// module.
1919
20+
use cmp;
2021
use comm::Port;
2122
use int;
2223
use iter::Iterator;
@@ -32,6 +33,9 @@ use sync::atomics;
3233
use vec::OwnedVector;
3334

3435
static DISCONNECTED: int = int::MIN;
36+
#[cfg(test)]
37+
static MAX_STEALS: int = 5;
38+
#[cfg(not(test))]
3539
static MAX_STEALS: int = 1 << 20;
3640

3741
pub struct Packet<T> {
@@ -198,19 +202,28 @@ impl<T: Send> Packet<T> {
198202
pub fn try_recv(&mut self) -> Result<T, Failure<T>> {
199203
match self.queue.pop() {
200204
// If we stole some data, record to that effect (this will be
201-
// factored into cnt later on). Note that we don't allow steals to
202-
// grow without bound in order to prevent eventual overflow of
203-
// either steals or cnt as an overflow would have catastrophic
204-
// results. Also note that we don't unconditionally set steals to 0
205-
// because it can be true that steals > cnt.
205+
// factored into cnt later on).
206+
//
207+
// Note that we don't allow steals to grow without bound in order to
208+
// prevent eventual overflow of either steals or cnt as an overflow
209+
// would have catastrophic results. Sometimes, steals > cnt, but
210+
// other times cnt > steals, so we don't know the relation between
211+
// steals and cnt. This code path is executed only rarely, so we do
212+
// a pretty slow operation, of swapping 0 into cnt, taking steals
213+
// down as much as possible (without going negative), and then
214+
// adding back in whatever we couldn't factor into steals.
206215
Some(data) => {
207216
self.steals += 1;
208217
if self.steals > MAX_STEALS {
209218
match self.cnt.swap(0, atomics::SeqCst) {
210219
DISCONNECTED => {
211220
self.cnt.store(DISCONNECTED, atomics::SeqCst);
212221
}
213-
n => { self.steals -= n; }
222+
n => {
223+
let m = cmp::min(n, self.steals);
224+
self.steals -= m;
225+
self.cnt.fetch_add(n - m, atomics::SeqCst);
226+
}
214227
}
215228
assert!(self.steals >= 0);
216229
}

0 commit comments

Comments
 (0)