Skip to main content

statime_netptp/
socket.rs

1use std::sync::Arc;
2
3use crate::{NetworkManagerData, PtpAddressFamily};
4
5mod recv;
6mod send;
7
8pub use recv::RecvResult;
9
10/// A socket not connected to a specific remote.
11///
12/// Can receive and send packets to any valid address of type `A`.
13pub struct OpenSocket<A: PtpAddressFamily> {
14    pub(crate) state: Arc<NetworkManagerData<A>>,
15    pub(crate) socket_id: usize,
16    pub(crate) packet_receiver: tokio::sync::mpsc::Receiver<RecvResult<A>>,
17}
18
19impl<A: PtpAddressFamily> Drop for OpenSocket<A> {
20    fn drop(&mut self) {
21        // The mutex can only be poisoned from an earlier panic. It is ok for
22        // us to propagate that to all the threads. The socket data will always
23        // be present.
24        let socket_data = self
25            .state
26            .sockets
27            .write()
28            .unwrap()
29            .remove(&self.socket_id)
30            .unwrap();
31        // The mutex can only be poisoned from an earlier panic. It is ok for
32        // us to propagate that to all the threads.
33        let mut interfaces = self.state.interfaces.write().unwrap();
34        // The interface will always be present because of the refcounting.
35        let entry = interfaces.get_mut(&socket_data.interface_filter).unwrap();
36        // An underflowing refcount should never happen. If it does, something
37        // is seriously wrong and aborting is the best solution.
38        entry.refcount = entry.refcount.checked_sub(1).unwrap();
39        if entry.refcount == 0 {
40            interfaces.remove(&socket_data.interface_filter);
41        }
42    }
43}
44
45/// A socket that connected to a specific remote.
46///
47/// Will only send and receive messages to the specific remote specified when
48/// opening the socket with [`Interface::connected_socket`](crate::Interface::connected_socket).
49pub struct ConnectedSocket<A: PtpAddressFamily> {
50    pub(crate) state: Arc<NetworkManagerData<A>>,
51    pub(crate) socket_id: usize,
52    pub(crate) packet_receiver: tokio::sync::mpsc::Receiver<RecvResult<A>>,
53}
54
55impl<A: PtpAddressFamily> Drop for ConnectedSocket<A> {
56    fn drop(&mut self) {
57        // The mutex can only be poisoned from an earlier panic. It is ok for
58        // us to propagate that to all the threads. The socket data will always
59        // be present.
60        let socket_data = self
61            .state
62            .sockets
63            .write()
64            .unwrap()
65            .remove(&self.socket_id)
66            .unwrap();
67        // The mutex can only be poisoned from an earlier panic. It is ok for
68        // us to propagate that to all the threads.
69        let mut interfaces = self.state.interfaces.write().unwrap();
70        // The interface will always be present because of the refcounting.
71        let entry = interfaces.get_mut(&socket_data.interface_filter).unwrap();
72        // An underflowing refcount should never happen. If it does, something
73        // is seriously wrong and aborting is the best solution.
74        entry.refcount = entry.refcount.checked_sub(1).unwrap();
75        if entry.refcount == 0 {
76            interfaces.remove(&socket_data.interface_filter);
77        }
78    }
79}