So far it is quite common to put the `AnyUnboundSocket` in an enum
variant, e.g. the following code snippet.
```rust
enum Inner {
Unbound(AlwaysSome<Box<AnyUnboundSocket>>),
Bound(AlwaysSome<Arc<AnyBoundSocket>>),
// ...
}
```
However, this pattern is very memory inefficient because the size
difference between two enum variants is significant. The size of
`AnyUnboundSocket` is much larger than the size of
`Arc<AnyBoundSocket>`, where the latter is simply a pointer and a
reference counter.
In fact, we're about to trigger Clippy's large_enum_variant warning.
We're just below its threshold, so the warning doesn't appear.
The solution is simple: If we put `AnyBoundSocket` in `Arc`, we should
also put `AnyUnboundSocket` in `Box`. This way the sizes of different
enum variants will be similar.
For TCP streams we have packed their different states with `Arc`, e.g.
`InitStream`, `ConnectedStream`, and `ListenStream`. Later we will
implement an trait that observes iface events for some of these states.
For UDP datagrams, they can be in the unbound state and the bound state.
If we want to implement the observer trait for the bound state, we need
to wrap it with `Arc` so that it can be registered with
`AnyBoundSocket`.
Alternatively, we can implement the observer trait directly on the UDP
datagram structure (i.e. `DatagramSocket`). However, there are literally
no events to handle if the socket is not bound at all (i.e. it is in the
unbound state). So a more efficient way is to implement the observer
trait only for the bound state, which motivates changes in this commit.
We used to use `is_nonblocking()` in TCP streams, but use
`nonblocking()` in UDP datagrams.
Since `is_nonblocking()` is generally preferred, this commit renames
`nonblocking()` to `is_nonblocking()` in UDP datagrams.