set.rs 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  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(_) => {
  63. panic!("adding a socket to a full SocketSet")
  64. }
  65. #[cfg(any(feature = "std", feature = "alloc"))]
  66. ManagedSlice::Owned(ref mut sockets) => {
  67. sockets.push(None);
  68. let index = sockets.len() - 1;
  69. put(index, &mut sockets[index], socket)
  70. }
  71. }
  72. }
  73. /// Get a socket from the set by its handle, as mutable.
  74. ///
  75. /// # Panics
  76. /// This function may panic if the handle does not belong to this socket set
  77. /// or the socket has the wrong type.
  78. pub fn get<T: AnySocket<'a>>(&mut self, handle: Handle) -> SocketRef<T> {
  79. match self.sockets[handle.0].as_mut() {
  80. Some(item) => T::downcast(SocketRef::new(&mut item.socket))
  81. .expect("handle refers to a socket of a wrong type"),
  82. None => panic!("handle does not refer to a valid socket"),
  83. }
  84. }
  85. /// Remove a socket from the set, without changing its state.
  86. ///
  87. /// # Panics
  88. /// This function may panic if the handle does not belong to this socket set.
  89. pub fn remove(&mut self, handle: Handle) -> Socket<'a> {
  90. net_trace!("[{}]: removing", handle.0);
  91. match self.sockets[handle.0].take() {
  92. Some(item) => item.socket,
  93. None => panic!("handle does not refer to a valid socket"),
  94. }
  95. }
  96. /// Increase reference count by 1.
  97. ///
  98. /// # Panics
  99. /// This function may panic if the handle does not belong to this socket set.
  100. pub fn retain(&mut self, handle: Handle) {
  101. self.sockets[handle.0]
  102. .as_mut()
  103. .expect("handle does not refer to a valid socket")
  104. .refs += 1
  105. }
  106. /// Decrease reference count by 1.
  107. ///
  108. /// # Panics
  109. /// This function may panic if the handle does not belong to this socket set,
  110. /// or if the reference count is already zero.
  111. pub fn release(&mut self, handle: Handle) {
  112. let refs = &mut self.sockets[handle.0]
  113. .as_mut()
  114. .expect("handle does not refer to a valid socket")
  115. .refs;
  116. if *refs == 0 {
  117. panic!("decreasing reference count past zero")
  118. }
  119. *refs -= 1
  120. }
  121. /// Prune the sockets in this set.
  122. ///
  123. /// Pruning affects sockets with reference count 0. Open sockets are closed.
  124. /// Closed sockets are removed and dropped.
  125. pub fn prune(&mut self) {
  126. for (index, item) in self.sockets.iter_mut().enumerate() {
  127. let mut may_remove = false;
  128. if let Some(Item {
  129. refs: 0,
  130. ref mut socket,
  131. }) = *item
  132. {
  133. match *socket {
  134. #[cfg(feature = "socket-raw")]
  135. Socket::Raw(_) => may_remove = true,
  136. #[cfg(all(
  137. feature = "socket-icmp",
  138. any(feature = "proto-ipv4", feature = "proto-ipv6")
  139. ))]
  140. Socket::Icmp(_) => may_remove = true,
  141. #[cfg(feature = "socket-udp")]
  142. Socket::Udp(_) => may_remove = true,
  143. #[cfg(feature = "socket-tcp")]
  144. Socket::Tcp(ref mut socket) => {
  145. if socket.state() == TcpState::Closed {
  146. may_remove = true
  147. } else {
  148. socket.close()
  149. }
  150. }
  151. #[cfg(feature = "socket-dhcpv4")]
  152. Socket::Dhcpv4(_) => may_remove = true,
  153. }
  154. }
  155. if may_remove {
  156. net_trace!("[{}]: pruning", index);
  157. *item = None
  158. }
  159. }
  160. }
  161. /// Iterate every socket in this set.
  162. pub fn iter<'d>(&'d self) -> Iter<'d, 'a> {
  163. Iter {
  164. lower: self.sockets.iter(),
  165. }
  166. }
  167. /// Iterate every socket in this set, as SocketRef.
  168. pub fn iter_mut<'d>(&'d mut self) -> IterMut<'d, 'a> {
  169. IterMut {
  170. lower: self.sockets.iter_mut(),
  171. }
  172. }
  173. }
  174. /// Immutable socket set iterator.
  175. ///
  176. /// This struct is created by the [iter](struct.SocketSet.html#method.iter)
  177. /// on [socket sets](struct.SocketSet.html).
  178. pub struct Iter<'a, 'b: 'a> {
  179. lower: slice::Iter<'a, Option<Item<'b>>>,
  180. }
  181. impl<'a, 'b: 'a> Iterator for Iter<'a, 'b> {
  182. type Item = &'a Socket<'b>;
  183. fn next(&mut self) -> Option<Self::Item> {
  184. for item_opt in &mut self.lower {
  185. if let Some(item) = item_opt.as_ref() {
  186. return Some(&item.socket);
  187. }
  188. }
  189. None
  190. }
  191. }
  192. /// Mutable socket set iterator.
  193. ///
  194. /// This struct is created by the [iter_mut](struct.SocketSet.html#method.iter_mut)
  195. /// on [socket sets](struct.SocketSet.html).
  196. pub struct IterMut<'a, 'b: 'a> {
  197. lower: slice::IterMut<'a, Option<Item<'b>>>,
  198. }
  199. impl<'a, 'b: 'a> Iterator for IterMut<'a, 'b> {
  200. type Item = SocketRef<'a, Socket<'b>>;
  201. fn next(&mut self) -> Option<Self::Item> {
  202. for item_opt in &mut self.lower {
  203. if let Some(item) = item_opt.as_mut() {
  204. return Some(SocketRef::new(&mut item.socket));
  205. }
  206. }
  207. None
  208. }
  209. }