1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//! This module contains tests that are written without relying on when the
//! garbage collector runs. Because tests are run in parallel, there's an edge
//! case that only impacts unit tests that prevents `collect()` from being
//! guaranteed to release values dropped directly before the call.
//!
//! This is an edge case would slow the garbage collector down slightly to
//! address, and it does not actually affect real-world use cases.
//!
//! # More info
//!
//! Consider the following series of events:
//!
//! | Test 1 | Test 2 | Collector |
//! |---------|---------|------------|
//! | start | | |
//! | guard | | start |
//! | <work> | | |
//! | collect | start | |
//! | | guard | locking |
//! | | <work> | |
//! | | collect | collecting |
//!
//! When a thread first accesses the garbage collector, it registers itself by
//! sending a message over a channel to the global collector. Once the garbage
//! collector begins its locking process, it will not process new messages on
//! that channel until it is done collecting.
//!
//! If test 2's guard acquisition succeeds before the collector begins locking
//! and its registration message arrives after the collector begins locking, the
//! garbage collector will not trace test 2's thread during the run it is
//! beginning. Test 2's thread will be traced on the next collection.
//!
//! This subtle behavior can cause tests that rely on values being dropped after
//! invoking collect to fail spuriously, but only when running multiple tests at
//! the same time.
//!
//! For this reason, most unit tests are written in the tests/ directory. When
//! executing `cargo test`, each of these files is executed independently.
use crate::;