set.rs 7.3 KB

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