chiark / gitweb /
Mutex debug: Introduce DebugIdentify trait
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 27 Mar 2022 12:32:24 +0000 (13:32 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 27 Mar 2022 23:50:50 +0000 (00:50 +0100)
And implement it for many of our types.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
src/bundles.rs
src/childio.rs
src/debugmutex.rs
src/global.rs
src/prelude.rs

index 6c2c5ea5dd07318b5a81d6a5beadaa236ab8697c..2dc4b715aa1ff1ff8d728bfa5bdfd8902a8847be 100644 (file)
@@ -312,6 +312,13 @@ impl Display for State {
   }
 }
 
+impl DebugIdentify for InstanceBundles {
+  #[throws(fmt::Error)]
+  fn debug_identify_type(f: &mut fmt::Formatter) {
+    write!(f, "InstanceBundles")?;
+  }
+}
+
 #[ext(pub)]
 impl MgmtBundleList {
   #[throws(IE)]
index 647a5e79cb6885a00d8c5a594dde7e7de39674c9..1a8e95136b8e5e945ab8cc39612a8603ee2af3e9 100644 (file)
@@ -30,6 +30,17 @@ impl Display for ChildWrapper {
   }
 }
 
+impl DebugIdentify for ChildWrapper {
+  #[throws(fmt::Error)]
+  fn debug_identify(&self, f: &mut fmt::Formatter) {
+    write!(f, "ChildWrapper([{}] {})", self.child.id(), &self.desc)?;
+  }
+  #[throws(fmt::Error)]
+  fn debug_identify_type(f: &mut fmt::Formatter) {
+    write!(f, "ChildWrapper")?;
+  }
+}
+
 impl<RW> ChildIo<RW> {
   fn rw_result(&self, eofblock: bool, r: io::Result<usize>)
                -> io::Result<usize>
index a9960fe817373b39b36861dc42de0172352ce212..46c532ab7cdd2d537f4898efa4c5b9e34ed6c66d 100644 (file)
@@ -5,9 +5,10 @@ use crate::prelude::*;
 pub struct Mutex<T>(parking_lot::Mutex<T>);
 
 #[derive(Debug, Display)]
-pub struct MutexGuard<'g, T>(parking_lot::MutexGuard<'g, T>);
+pub struct MutexGuard<'g, T>(parking_lot::MutexGuard<'g, T>)
+where T: DebugIdentify;
 
-impl<T> Mutex<T> {
+impl<T> Mutex<T> where T: DebugIdentify {
   pub fn new(t: T) -> Self {
     Mutex(parking_lot::Mutex::new(t))
   }
@@ -16,10 +17,66 @@ impl<T> Mutex<T> {
   }
 }
 
-impl<'g,T> Deref for MutexGuard<'g,T> {
+impl<'g,T> Deref for MutexGuard<'g,T> where T: DebugIdentify {
   type Target = T;
   fn deref(&self) -> &T { &*self.0 }
 }
-impl<'g,T> DerefMut for MutexGuard<'g,T> {
+impl<'g,T> DerefMut for MutexGuard<'g,T> where T: DebugIdentify {
   fn deref_mut(&mut self) -> &mut T { &mut *self.0 }
 }
+
+pub struct DisplayFormatter<F>(F);
+impl<F> Display for DisplayFormatter<F>
+where F: Fn(&mut fmt::Formatter) -> fmt::Result {
+  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.0(f) }
+}
+
+pub struct DisplayDebugIdentify<'t,T>(&'t T) where T: DebugIdentify;
+impl<T> Display for DisplayDebugIdentify<'_,T> where T: DebugIdentify {
+  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    self.0.debug_identify(f)
+  }
+}
+
+pub trait DebugIdentify {
+  fn debug_identify_type(f: &mut fmt::Formatter) -> fmt::Result;
+  fn debug_identify(&self, f: &mut fmt::Formatter) -> fmt::Result {
+    Self::debug_identify_type(f)?;
+    write!(f, "({:?})", self as *const _)?;
+    Ok(())
+  }
+}
+
+impl<T> DebugIdentify for Option<T> where T: DebugIdentify {
+  #[throws(fmt::Error)]
+  fn debug_identify_type(f: &mut fmt::Formatter) {
+    write!(f, "Option<{}>", DisplayFormatter(T::debug_identify_type))?;
+  }
+
+  #[throws(fmt::Error)]
+  fn debug_identify(&self, f: &mut fmt::Formatter) {
+    match self {
+      None => write!(f, "None<{}>", DisplayFormatter(T::debug_identify_type))?,
+      Some(t) => t.debug_identify(f)?,
+    }
+  }
+}
+
+impl<T> DebugIdentify for VecDeque<T> where T: DebugIdentify {
+  #[throws(fmt::Error)]
+  fn debug_identify_type(f: &mut fmt::Formatter) {
+    write!(f, "VecDeque<{}>", DisplayFormatter(T::debug_identify_type))?;
+  }
+}
+
+impl DebugIdentify for File{
+  #[throws(fmt::Error)]
+  fn debug_identify_type(f: &mut fmt::Formatter) {
+    write!(f, "File")?;
+  }
+
+  #[throws(fmt::Error)]
+  fn debug_identify(&self, f: &mut fmt::Formatter) {
+    write!(f, "File({})", self.as_raw_fd())?;
+  }
+}
index 83ff49a03ea5a397649b4ee5ae8a94b39f1754c8..7587ed9245f13878de101cf565eb5dc1ce2a4ed7 100644 (file)
@@ -566,6 +566,24 @@ impl Display for InstanceName {
 }
 hformat_as_display!{InstanceName}
 
+impl DebugIdentify for InstanceContainer {
+  #[throws(fmt::Error)]
+  fn debug_identify(&self, f: &mut fmt::Formatter) {
+    write!(f, "InstanceContainer({})", &self.g.name)?;
+  }
+  #[throws(fmt::Error)]
+  fn debug_identify_type(f: &mut fmt::Formatter) {
+    write!(f, "InstanceContainer")?;
+  }
+}
+
+impl DebugIdentify for InstanceRef {
+  #[throws(fmt::Error)]
+  fn debug_identify_type(f: &mut fmt::Formatter) {
+    write!(f, "InstanceRef")?;
+  }
+}
+
 fn link_a_href(k: &HtmlStr, v: &str) -> Html {
   hformat!("<a href={}>{}</a>", v, k)
 }
index 882381c1037b7e05d1a45c5cf1a35fe72f39ce51..2dfb5cd9082089809185ed00c5e456ab06185fe0 100644 (file)
@@ -147,6 +147,7 @@ pub use crate::commands::{MgmtGameInstruction, MgmtGameResponse};
 pub use crate::commands::{MgmtBundleList, MgmtGameUpdateMode};
 pub use crate::commands::{ProgressUpdateMode};
 pub use crate::config::*;
+pub use crate::debugmutex::DebugIdentify;
 pub use crate::debugreader::DebugReader;
 pub use crate::error::*;
 pub use crate::fake_rng::*;