set.rs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. use core::{fmt, slice};
  2. use managed::ManagedSlice;
  3. #[cfg(feature = "socket-tcp")]
  4. use crate::socket::TcpState;
  5. use crate::socket::{AnySocket, Socket, SocketRef};
  6. /// An item of a socket set.
  7. ///
  8. /// The only reason this struct is public is to allow the socket set storage
  9. /// to be allocated externally.
  10. #[derive(Debug)]
  11. pub struct Item<'a> {
  12. socket: Socket<'a>,
  13. refs: usize,
  14. }
  15. /// A handle, identifying a socket in a set.
  16. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
  17. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  18. pub struct Handle(usize);
  19. impl fmt::Display for Handle {
  20. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  21. write!(f, "#{}", self.0)
  22. }
  23. }
  24. /// An extensible set of sockets.
  25. ///
  26. /// The lifetime `'a` is used when storing a `Socket<'a>`.
  27. #[derive(Debug)]
  28. pub struct Set<'a> {
  29. sockets: ManagedSlice<'a, Option<Item<'a>>>,
  30. }
  31. impl<'a> Set<'a> {
  32. /// Create a socket set using the provided storage.
  33. pub fn new<SocketsT>(sockets: SocketsT) -> Set<'a>
  34. where
  35. SocketsT: Into<ManagedSlice<'a, Option<Item<'a>>>>,
  36. {
  37. let sockets = sockets.into();
  38. Set { sockets }
  39. }
  40. /// Add a socket to the set with the reference count 1, and return its handle.
  41. ///
  42. /// # Panics
  43. /// This function panics if the storage is fixed-size (not a `Vec`) and is full.
  44. pub fn add<T>(&mut self, socket: T) -> Handle
  45. where
  46. T: Into<Socket<'a>>,
  47. {
  48. fn put<'a>(index: usize, slot: &mut Option<Item<'a>>, mut socket: Socket<'a>) -> Handle {
  49. net_trace!("[{}]: adding", index);
  50. let handle = Handle(index);
  51. socket.meta_mut().handle = handle;
  52. *slot = Some(Item { socket, refs: 1 });
  53. handle
  54. }
  55. let socket = socket.into();
  56. for (index, slot) in self.sockets.iter_mut().enumerate() {
  57. if slot.is_none() {
  58. return put(index, slot, socket);
  59. }
  60. }
  61. match self.sockets {
  62. ManagedSlice::Borrowed(_) => panic!("adding a socket to a full SocketSet"),
  63. #[cfg(any(feature = "std", feature = "alloc"))]
  64. ManagedSlice::Owned(ref mut sockets) => {
  65. sockets.push(None);
  66. let index = sockets.len() - 1;
  67. put(index, &mut sockets[index], socket)
  68. }
  69. }
  70. }
  71. /// Get a socket from the set by its handle, as mutable.
  72. ///
  73. /// # Panics
  74. /// This function may panic if the handle does not belong to this socket set
  75. /// or the socket has the wrong type.
  76. pub fn get<T: AnySocket<'a>>(&mut self, handle: Handle) -> SocketRef<T> {
  77. match self.sockets[handle.0].as_mut() {
  78. Some(item) => T::downcast(SocketRef::new(&mut item.socket))
  79. .expect("handle refers to a socket of a wrong type"),
  80. None => panic!("handle does not refer to a valid socket"),
  81. }
  82. }
  83. /// Remove a socket from the set, without changing its state.
  84. ///
  85. /// # Panics
  86. /// This function may panic if the handle does not belong to this socket set.
  87. pub fn remove(&mut self, handle: Handle) -> Socket<'a> {
  88. net_trace!("[{}]: removing", handle.0);
  89. match self.sockets[handle.0].take() {
  90. Some(item) => item.socket,
  91. None => panic!("handle does not refer to a valid socket"),
  92. }
  93. }
  94. /// Increase reference count by 1.
  95. ///
  96. /// # Panics
  97. /// This function may panic if the handle does not belong to this socket set.
  98. pub fn retain(&mut self, handle: Handle) {
  99. self.sockets[handle.0]
  100. .as_mut()
  101. .expect("handle does not refer to a valid socket")
  102. .refs += 1
  103. }
  104. /// Decrease reference count by 1.
  105. ///
  106. /// # Panics
  107. /// This function may panic if the handle does not belong to this socket set,
  108. /// or if the reference count is already zero.
  109. pub fn release(&mut self, handle: Handle) {
  110. let refs = &mut self.sockets[handle.0]
  111. .as_mut()
  112. .expect("handle does not refer to a valid socket")
  113. .refs;
  114. if *refs == 0 {
  115. panic!("decreasing reference count past zero")
  116. }
  117. *refs -= 1
  118. }
  119. /// Prune the sockets in this set.
  120. ///
  121. /// Pruning affects sockets with reference count 0. Open sockets are closed.
  122. /// Closed sockets are removed and dropped.
  123. pub fn prune(&mut self) {
  124. for (index, item) in self.sockets.iter_mut().enumerate() {
  125. let mut may_remove = false;
  126. if let Some(Item {
  127. refs: 0,
  128. ref mut socket,
  129. }) = *item
  130. {
  131. match *socket {
  132. #[cfg(feature = "socket-raw")]
  133. Socket::Raw(_) => may_remove = true,
  134. #[cfg(all(
  135. feature = "socket-icmp",
  136. any(feature = "proto-ipv4", feature = "proto-ipv6")
  137. ))]
  138. Socket::Icmp(_) => may_remove = true,
  139. #[cfg(feature = "socket-udp")]
  140. Socket::Udp(_) => may_remove = true,
  141. #[cfg(feature = "socket-tcp")]
  142. Socket::Tcp(ref mut socket) => {
  143. if socket.state() == TcpState::Closed {
  144. may_remove = true
  145. } else {
  146. socket.close()
  147. }
  148. }
  149. #[cfg(feature = "socket-dhcpv4")]
  150. Socket::Dhcpv4(_) => may_remove = true,
  151. }
  152. }
  153. if may_remove {
  154. net_trace!("[{}]: pruning", index);
  155. *item = None
  156. }
  157. }
  158. }
  159. /// Iterate every socket in this set.
  160. pub fn iter<'d>(&'d self) -> Iter<'d, 'a> {
  161. Iter {
  162. lower: self.sockets.iter(),
  163. }
  164. }
  165. /// Iterate every socket in this set, as SocketRef.
  166. pub fn iter_mut<'d>(&'d mut self) -> IterMut<'d, 'a> {
  167. IterMut {
  168. lower: self.sockets.iter_mut(),
  169. }
  170. }
  171. }
  172. /// Immutable socket set iterator.
  173. ///
  174. /// This struct is created by the [iter](struct.SocketSet.html#method.iter)
  175. /// on [socket sets](struct.SocketSet.html).
  176. pub struct Iter<'a, 'b: 'a> {
  177. lower: slice::Iter<'a, Option<Item<'b>>>,
  178. }
  179. impl<'a, 'b: 'a> Iterator for Iter<'a, 'b> {
  180. type Item = &'a Socket<'b>;
  181. fn next(&mut self) -> Option<Self::Item> {
  182. for item_opt in &mut self.lower {
  183. if let Some(item) = item_opt.as_ref() {
  184. return Some(&item.socket);
  185. }
  186. }
  187. None
  188. }
  189. }
  190. /// Mutable socket set iterator.
  191. ///
  192. /// This struct is created by the [iter_mut](struct.SocketSet.html#method.iter_mut)
  193. /// on [socket sets](struct.SocketSet.html).
  194. pub struct IterMut<'a, 'b: 'a> {
  195. lower: slice::IterMut<'a, Option<Item<'b>>>,
  196. }
  197. impl<'a, 'b: 'a> Iterator for IterMut<'a, 'b> {
  198. type Item = SocketRef<'a, Socket<'b>>;
  199. fn next(&mut self) -> Option<Self::Item> {
  200. for item_opt in &mut self.lower {
  201. if let Some(item) = item_opt.as_mut() {
  202. return Some(SocketRef::new(&mut item.socket));
  203. }
  204. }
  205. None
  206. }
  207. }