component.rs 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. macro_rules! component {
  2. ($name:ident : $inner:ident { $($key:ident : $ty:ty = $value:expr,)* }) => {
  3. #[derive(Clone)]
  4. pub struct $name(::std::sync::Arc<($crate::session::SessionWeak, ::std::sync::Mutex<$inner>)>);
  5. impl $name {
  6. #[allow(dead_code)]
  7. pub(crate) fn new(session: $crate::session::SessionWeak) -> $name {
  8. debug!(target:"librespot::component", "new {}", stringify!($name));
  9. $name(::std::sync::Arc::new((session, ::std::sync::Mutex::new($inner {
  10. $($key : $value,)*
  11. }))))
  12. }
  13. #[allow(dead_code)]
  14. fn lock<F: FnOnce(&mut $inner) -> R, R>(&self, f: F) -> R {
  15. let mut inner = (self.0).1.lock().expect("Mutex poisoned");
  16. f(&mut inner)
  17. }
  18. #[allow(dead_code)]
  19. fn session(&self) -> $crate::session::Session {
  20. (self.0).0.upgrade()
  21. }
  22. }
  23. struct $inner {
  24. $($key : $ty,)*
  25. }
  26. impl Drop for $inner {
  27. fn drop(&mut self) {
  28. debug!(target:"librespot::component", "drop {}", stringify!($name));
  29. }
  30. }
  31. }
  32. }
  33. use std::cell::UnsafeCell;
  34. use std::sync::Mutex;
  35. pub(crate) struct Lazy<T>(Mutex<bool>, UnsafeCell<Option<T>>);
  36. unsafe impl<T: Sync> Sync for Lazy<T> {}
  37. unsafe impl<T: Send> Send for Lazy<T> {}
  38. #[cfg_attr(feature = "cargo-clippy", allow(mutex_atomic))]
  39. impl<T> Lazy<T> {
  40. pub(crate) fn new() -> Lazy<T> {
  41. Lazy(Mutex::new(false), UnsafeCell::new(None))
  42. }
  43. pub(crate) fn get<F: FnOnce() -> T>(&self, f: F) -> &T {
  44. let mut inner = self.0.lock().unwrap();
  45. if !*inner {
  46. unsafe {
  47. *self.1.get() = Some(f());
  48. }
  49. *inner = true;
  50. }
  51. unsafe { &*self.1.get() }.as_ref().unwrap()
  52. }
  53. }