Skip to content

Commit 4fa269c

Browse files
committed
---
yaml --- r: 59374 b: refs/heads/snap-stage3 c: ebe35f3 h: refs/heads/master v: v3
1 parent c3a4449 commit 4fa269c

File tree

5 files changed

+158
-96
lines changed

5 files changed

+158
-96
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: c081ffbd1e845687202a975ea2e698b623e5722f
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: d2f0235a2c887e425b2c06b8df359b1400b8dd4d
4+
refs/heads/snap-stage3: ebe35f3873b0ad48d48b009a871843e583584379
55
refs/heads/try: c50a9d5b664478e533ba1d1d353213d70c8ad589
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/libcore/hashmap.rs

Lines changed: 75 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -347,16 +347,27 @@ impl<K:Hash + Eq,V> Map<K, V> for HashMap<K, V> {
347347
}
348348
349349
/// Return a mutable reference to the value corresponding to the key
350+
#[cfg(stage0)]
350351
fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> {
351352
let idx = match self.bucket_for_key(k) {
352353
FoundEntry(idx) => idx,
353354
TableFull | FoundHole(_) => return None
354355
};
355-
unsafe { // FIXME(#4903)---requires flow-sensitive borrow checker
356+
unsafe {
356357
Some(::cast::transmute_mut_region(self.mut_value_for_bucket(idx)))
357358
}
358359
}
359360
361+
/// Return a mutable reference to the value corresponding to the key
362+
#[cfg(not(stage0))]
363+
fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> {
364+
let idx = match self.bucket_for_key(k) {
365+
FoundEntry(idx) => idx,
366+
TableFull | FoundHole(_) => return None
367+
};
368+
Some(self.mut_value_for_bucket(idx))
369+
}
370+
360371
/// Insert a key-value pair into the map. An existing value for a
361372
/// key is replaced by the new value. Return true if the key did
362373
/// not already exist in the map.
@@ -429,6 +440,7 @@ pub impl<K: Hash + Eq, V> HashMap<K, V> {
429440
430441
/// Return the value corresponding to the key in the map, or insert
431442
/// and return the value if it doesn't exist.
443+
#[cfg(stage0)]
432444
fn find_or_insert<'a>(&'a mut self, k: K, v: V) -> &'a V {
433445
if self.size >= self.resize_at {
434446
// n.b.: We could also do this after searching, so
@@ -452,13 +464,43 @@ pub impl<K: Hash + Eq, V> HashMap<K, V> {
452464
},
453465
};
454466
455-
unsafe { // FIXME(#4903)---requires flow-sensitive borrow checker
467+
unsafe {
456468
::cast::transmute_region(self.value_for_bucket(idx))
457469
}
458470
}
459471
472+
/// Return the value corresponding to the key in the map, or insert
473+
/// and return the value if it doesn't exist.
474+
#[cfg(not(stage0))]
475+
fn find_or_insert<'a>(&'a mut self, k: K, v: V) -> &'a V {
476+
if self.size >= self.resize_at {
477+
// n.b.: We could also do this after searching, so
478+
// that we do not resize if this call to insert is
479+
// simply going to update a key in place. My sense
480+
// though is that it's worse to have to search through
481+
// buckets to find the right spot twice than to just
482+
// resize in this corner case.
483+
self.expand();
484+
}
485+
486+
let hash = k.hash_keyed(self.k0, self.k1) as uint;
487+
let idx = match self.bucket_for_key_with_hash(hash, &k) {
488+
TableFull => fail!(~"Internal logic error"),
489+
FoundEntry(idx) => idx,
490+
FoundHole(idx) => {
491+
self.buckets[idx] = Some(Bucket{hash: hash, key: k,
492+
value: v});
493+
self.size += 1;
494+
idx
495+
},
496+
};
497+
498+
self.value_for_bucket(idx)
499+
}
500+
460501
/// Return the value corresponding to the key in the map, or create,
461502
/// insert, and return a new value if it doesn't exist.
503+
#[cfg(stage0)]
462504
fn find_or_insert_with<'a>(&'a mut self, k: K, f: &fn(&K) -> V) -> &'a V {
463505
if self.size >= self.resize_at {
464506
// n.b.: We could also do this after searching, so
@@ -483,11 +525,41 @@ pub impl<K: Hash + Eq, V> HashMap<K, V> {
483525
},
484526
};
485527
486-
unsafe { // FIXME(#4903)---requires flow-sensitive borrow checker
528+
unsafe {
487529
::cast::transmute_region(self.value_for_bucket(idx))
488530
}
489531
}
490532
533+
/// Return the value corresponding to the key in the map, or create,
534+
/// insert, and return a new value if it doesn't exist.
535+
#[cfg(not(stage0))]
536+
fn find_or_insert_with<'a>(&'a mut self, k: K, f: &fn(&K) -> V) -> &'a V {
537+
if self.size >= self.resize_at {
538+
// n.b.: We could also do this after searching, so
539+
// that we do not resize if this call to insert is
540+
// simply going to update a key in place. My sense
541+
// though is that it's worse to have to search through
542+
// buckets to find the right spot twice than to just
543+
// resize in this corner case.
544+
self.expand();
545+
}
546+
547+
let hash = k.hash_keyed(self.k0, self.k1) as uint;
548+
let idx = match self.bucket_for_key_with_hash(hash, &k) {
549+
TableFull => fail!(~"Internal logic error"),
550+
FoundEntry(idx) => idx,
551+
FoundHole(idx) => {
552+
let v = f(&k);
553+
self.buckets[idx] = Some(Bucket{hash: hash, key: k,
554+
value: v});
555+
self.size += 1;
556+
idx
557+
},
558+
};
559+
560+
self.value_for_bucket(idx)
561+
}
562+
491563
fn consume(&mut self, f: &fn(K, V)) {
492564
let mut buckets = ~[];
493565
self.buckets <-> buckets;

branches/snap-stage3/src/libcore/run.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -855,4 +855,74 @@ mod tests {
855855
fn waitpid_non_existant_pid() {
856856
run::waitpid(123456789); // assume that this pid doesn't exist
857857
}
858+
859+
#[test]
860+
fn test_destroy_once() {
861+
let mut p = run::start_program("echo", []);
862+
p.destroy(); // this shouldn't crash (and nor should the destructor)
863+
}
864+
865+
#[test]
866+
fn test_destroy_twice() {
867+
let mut p = run::start_program("echo", []);
868+
p.destroy(); // this shouldnt crash...
869+
p.destroy(); // ...and nor should this (and nor should the destructor)
870+
}
871+
872+
fn test_destroy_actually_kills(force: bool) {
873+
874+
#[cfg(unix)]
875+
static BLOCK_COMMAND: &'static str = "cat";
876+
877+
#[cfg(windows)]
878+
static BLOCK_COMMAND: &'static str = "cmd";
879+
880+
#[cfg(unix)]
881+
fn process_exists(pid: libc::pid_t) -> bool {
882+
run::program_output("ps", [~"-p", pid.to_str()]).out.contains(pid.to_str())
883+
}
884+
885+
#[cfg(windows)]
886+
fn process_exists(pid: libc::pid_t) -> bool {
887+
888+
use libc::types::os::arch::extra::DWORD;
889+
use libc::funcs::extra::kernel32::{CloseHandle, GetExitCodeProcess, OpenProcess};
890+
use libc::consts::os::extra::{FALSE, PROCESS_QUERY_INFORMATION, STILL_ACTIVE };
891+
892+
unsafe {
893+
let proc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid as DWORD);
894+
if proc.is_null() {
895+
return false;
896+
}
897+
// proc will be non-null if the process is alive, or if it died recently
898+
let mut status = 0;
899+
GetExitCodeProcess(proc, &mut status);
900+
CloseHandle(proc);
901+
return status == STILL_ACTIVE;
902+
}
903+
}
904+
905+
// this program will stay alive indefinitely trying to read from stdin
906+
let mut p = run::start_program(BLOCK_COMMAND, []);
907+
908+
assert!(process_exists(p.get_id()));
909+
910+
if force {
911+
p.force_destroy();
912+
} else {
913+
p.destroy();
914+
}
915+
916+
assert!(!process_exists(p.get_id()));
917+
}
918+
919+
#[test]
920+
fn test_unforced_destroy_actually_kills() {
921+
test_destroy_actually_kills(false);
922+
}
923+
924+
#[test]
925+
fn test_forced_destroy_actually_kills() {
926+
test_destroy_actually_kills(true);
927+
}
858928
}

branches/snap-stage3/src/libcore/trie.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,9 @@ fn chunk(n: uint, idx: uint) -> uint {
276276
(n >> sh) & MASK
277277
}
278278

279-
fn find_mut<'r, T>(child: &'r mut Child<T>, key: uint, idx: uint)
280-
-> Option<&'r mut T> {
281-
unsafe { // FIXME(#4903)---requires flow-sensitive borrow checker
279+
#[cfg(stage0)]
280+
fn find_mut<'r, T>(child: &'r mut Child<T>, key: uint, idx: uint) -> Option<&'r mut T> {
281+
unsafe {
282282
(match *child {
283283
External(_, ref value) => Some(cast::transmute_mut(value)),
284284
Internal(ref x) => find_mut(cast::transmute_mut(&x.children[chunk(key, idx)]),
@@ -288,6 +288,15 @@ fn find_mut<'r, T>(child: &'r mut Child<T>, key: uint, idx: uint)
288288
}
289289
}
290290

291+
#[cfg(not(stage0))]
292+
fn find_mut<'r, T>(child: &'r mut Child<T>, key: uint, idx: uint) -> Option<&'r mut T> {
293+
match *child {
294+
External(_, ref mut value) => Some(value),
295+
Internal(ref mut x) => find_mut(&mut x.children[chunk(key, idx)], key, idx + 1),
296+
Nothing => None
297+
}
298+
}
299+
291300
fn insert<T>(count: &mut uint, child: &mut Child<T>, key: uint, value: T,
292301
idx: uint) -> bool {
293302
let mut tmp = Nothing;

branches/snap-stage3/src/test/run-pass/core-run-destroy.rs

Lines changed: 0 additions & 89 deletions
This file was deleted.

0 commit comments

Comments
 (0)