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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
//! Thespis_impl supports both strong and weak addresses. When all strong addresses to a mailbox are
//! dropped, the mailbox will shut down.
//!
//! The logic is that sending is already fallible, so a weak address will deny sending with an error
//! messages if the strong count is zero. However the mailbox will still continue processing all messages
//! already in the queue and stop as soon as the queue is empty.
//!
//! This solution must support the following scenarios:
//! - WeakAddr must be able to check the count before allowing sending.
//! - When a WeakAddr is pending on a full queue and strong count goes to zero, should we return error?
//! If we err, can we let the user recover their message? What is then the type of the message in the
//! error enum? It would mean that the weak address has to be woken up in from the pending state when
//! strong count goes to zero. -> Seems like pretty complicated, better consider that if the weak address already
//! accepted the message, it will now be processed.
//! - A WeakAddr must be able to upgrade to strong as long as the strong count has never been zero.
//! - When the mailbox is pending, eg. queue is empty and strong count goes to zero, it must be woken up.
//! - When the mailbox is processing and strong count goes to zero, when it becomes pending, eg. the
//! queue is now empty it must be able to check that and must be able to break from the pending state and shut down.
//! - Strong addresses must be able to decrement the counter in Drop, eg. non-async context.
//!
//! Current solution has us wrapping the channel receiver to intercept the `Pending` state. It will then
//! check the strong count, and if it should remain alive, register it's waker so the task gets woken
//! up in case the count goes to zero.
//!
use Waker;
use crate::;
use AtomicWaker;
use ;
//
/// Type that represents an async counter that will keep track of how many `Addr` exist for a mailbox.
/// This allows to shut down the mailbox when there are only `WeakAddr` left alive.
///
/// This can be cloned to give copies to both `Addr::new` and `ChanReceiver::new`.
//
//
pub