1use std::cell::RefCell;
2use std::hash::Hasher;
3use std::{
4 collections::{HashMap, HashSet},
5 fmt::Debug,
6 hash::Hash,
7 marker::PhantomData,
8 sync::{
9 atomic::{AtomicU64, Ordering},
10 Arc, Mutex, RwLock,
11 },
12};
13
14use crate::ArtifactId;
15use crossbeam_channel::Sender;
16use serde::{de, ser, Deserialize, Serialize};
17use uuid::Uuid;
18
19#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
22pub struct LoadHandle(pub u64);
23
24impl LoadHandle {
25 pub fn new(
26 load_handle: u64,
27 is_indirect: bool,
28 ) -> Self {
29 if is_indirect {
30 Self(load_handle | (1 << 63))
31 } else {
32 Self(load_handle)
33 }
34 }
35
36 pub fn is_indirect(&self) -> bool {
44 (self.0 & (1 << 63)) == 1 << 63
45 }
46}
47
48#[derive(Debug, Hash, PartialEq, Eq, Clone, Ord, PartialOrd, Serialize, Deserialize)]
50pub struct ArtifactRef(pub ArtifactId);
51
52pub trait LoaderInfoProvider: Send + Sync {
55 fn resolved_load_handle(
63 &self,
64 artifact_ref: &ArtifactRef,
65 ) -> Option<Arc<ResolvedLoadHandle>>;
66
67 fn artifact_id(
73 &self,
74 load: LoadHandle,
75 ) -> Option<ArtifactId>;
76}
77
78#[derive(Debug)]
79pub struct ResolvedLoadHandle {
80 pub id: LoadHandle,
81 pub direct_load_handle: AtomicU64,
82}
83
84impl PartialEq for ResolvedLoadHandle {
85 fn eq(
86 &self,
87 other: &Self,
88 ) -> bool {
89 self.id == other.id
91 }
92}
93
94impl Eq for ResolvedLoadHandle {}
95
96impl Hash for ResolvedLoadHandle {
97 fn hash<H: Hasher>(
98 &self,
99 state: &mut H,
100 ) {
101 self.id.hash(state)
103 }
104}
105
106impl ResolvedLoadHandle {
107 pub fn new(
108 id: LoadHandle,
109 resolved_load_handle: LoadHandle,
110 ) -> Arc<Self> {
111 Arc::new(ResolvedLoadHandle {
112 id,
113 direct_load_handle: AtomicU64::new(resolved_load_handle.0),
114 })
115 }
116
117 pub fn new_null_handle() -> Arc<Self> {
118 Arc::new(ResolvedLoadHandle {
119 id: LoadHandle(0),
120 direct_load_handle: AtomicU64::default(),
121 })
122 }
123
124 pub fn direct_load_handle(&self) -> LoadHandle {
125 LoadHandle(self.direct_load_handle.load(Ordering::Relaxed))
126 }
127}
128
129#[derive(Debug)]
131pub enum RefOp {
132 Decrease(LoadHandle),
133 Increase(LoadHandle),
134}
135
136#[derive(Debug)]
138pub enum HandleRefType {
139 Strong(Sender<RefOp>),
141 Weak(Sender<RefOp>),
143 Internal(Sender<RefOp>),
146 None,
148}
149
150struct HandleRef {
151 resolved_load_handle: Arc<ResolvedLoadHandle>,
152 ref_type: HandleRefType,
153}
154impl PartialEq for HandleRef {
155 fn eq(
156 &self,
157 other: &Self,
158 ) -> bool {
159 self.resolved_load_handle
160 .id
161 .eq(&other.resolved_load_handle.id)
162 }
163}
164impl Hash for HandleRef {
165 fn hash<H: std::hash::Hasher>(
166 &self,
167 state: &mut H,
168 ) {
169 self.resolved_load_handle.id.hash(state)
170 }
171}
172impl Eq for HandleRef {}
173impl Debug for HandleRef {
174 fn fmt(
175 &self,
176 f: &mut std::fmt::Formatter<'_>,
177 ) -> std::fmt::Result {
178 self.resolved_load_handle.id.fmt(f)
179 }
180}
181
182impl Drop for HandleRef {
183 fn drop(&mut self) {
184 use HandleRefType::*;
185 self.ref_type = match std::mem::replace(&mut self.ref_type, None) {
186 Strong(sender) => {
187 let _ = sender.send(RefOp::Decrease(self.resolved_load_handle.id));
188 Weak(sender)
189 }
190 r => r,
191 };
192 }
193}
194
195impl Clone for HandleRef {
196 fn clone(&self) -> Self {
197 use HandleRefType::*;
198 Self {
199 resolved_load_handle: self.resolved_load_handle.clone(),
200 ref_type: match &self.ref_type {
201 Internal(sender) | Strong(sender) => {
202 let _ = sender.send(RefOp::Increase(self.resolved_load_handle.id));
203 Strong(sender.clone())
204 }
205 Weak(sender) => Weak(sender.clone()),
206 None => panic!("unexpected ref type in clone()"),
207 },
208 }
209 }
210}
211
212impl ArtifactHandle for HandleRef {
213 fn resolved_load_handle(&self) -> &Arc<ResolvedLoadHandle> {
214 &self.resolved_load_handle
215 }
216}
217
218#[derive(Eq)]
220pub struct Handle<T: ?Sized> {
221 handle_ref: HandleRef,
222 marker: PhantomData<T>,
223}
224
225impl<T: ?Sized> PartialEq for Handle<T> {
226 fn eq(
227 &self,
228 other: &Self,
229 ) -> bool {
230 self.handle_ref == other.handle_ref
231 }
232}
233
234impl<T: ?Sized> Clone for Handle<T> {
235 fn clone(&self) -> Self {
236 Self {
237 handle_ref: self.handle_ref.clone(),
238 marker: PhantomData,
239 }
240 }
241}
242
243impl<T: ?Sized> Hash for Handle<T> {
244 fn hash<H: std::hash::Hasher>(
245 &self,
246 state: &mut H,
247 ) {
248 self.handle_ref.hash(state);
249 }
250}
251
252impl<T: ?Sized> Debug for Handle<T> {
253 fn fmt(
254 &self,
255 f: &mut std::fmt::Formatter<'_>,
256 ) -> std::fmt::Result {
257 f.debug_struct("Handle")
258 .field("handle_ref", &self.handle_ref)
259 .finish()
260 }
261}
262
263impl<T: ?Sized> From<GenericHandle> for Handle<T> {
264 fn from(handle: GenericHandle) -> Self {
265 Self {
266 handle_ref: handle.handle_ref,
267 marker: PhantomData,
268 }
269 }
270}
271
272impl<T> Handle<T> {
273 pub fn new(
275 chan: Sender<RefOp>,
276 resolved_load_handle: Arc<ResolvedLoadHandle>,
277 ) -> Self {
278 Self {
279 handle_ref: HandleRef {
280 resolved_load_handle,
281 ref_type: HandleRefType::Strong(chan),
282 },
283 marker: PhantomData,
284 }
285 }
286
287 pub(crate) fn new_internal(
289 chan: Sender<RefOp>,
290 resolved_load_handle: Arc<ResolvedLoadHandle>,
291 ) -> Self {
292 Self {
293 handle_ref: HandleRef {
294 resolved_load_handle,
295 ref_type: HandleRefType::Internal(chan),
296 },
297 marker: PhantomData,
298 }
299 }
300
301 pub fn artifact<'a>(
302 &self,
303 storage: &'a impl TypedArtifactStorage<T>,
304 ) -> Option<&'a T> {
305 ArtifactHandle::artifact(self, storage)
306 }
307}
308
309impl<T> ArtifactHandle for Handle<T> {
310 fn resolved_load_handle(&self) -> &Arc<ResolvedLoadHandle> {
311 &self.handle_ref.resolved_load_handle
312 }
313}
314
315#[derive(Debug, Clone, PartialEq, Eq, Hash)]
319pub struct GenericHandle {
320 handle_ref: HandleRef,
321}
322
323impl GenericHandle {
324 pub fn new(
326 chan: Sender<RefOp>,
327 resolved_load_handle: Arc<ResolvedLoadHandle>,
328 ) -> Self {
329 Self {
330 handle_ref: HandleRef {
331 resolved_load_handle,
332 ref_type: HandleRefType::Strong(chan),
333 },
334 }
335 }
336
337 pub(crate) fn new_internal(
339 chan: Sender<RefOp>,
340 resolved_load_handle: Arc<ResolvedLoadHandle>,
341 ) -> Self {
342 Self {
343 handle_ref: HandleRef {
344 resolved_load_handle,
345 ref_type: HandleRefType::Internal(chan),
346 },
347 }
348 }
349}
350
351impl ArtifactHandle for GenericHandle {
352 fn resolved_load_handle(&self) -> &Arc<ResolvedLoadHandle> {
353 &self.handle_ref.resolved_load_handle
354 }
355}
356
357impl<T: ?Sized> From<Handle<T>> for GenericHandle {
358 fn from(handle: Handle<T>) -> Self {
359 Self {
360 handle_ref: handle.handle_ref,
361 }
362 }
363}
364
365#[derive(Clone, Eq, Hash, PartialEq, Debug)]
374pub struct WeakHandle {
375 resolved_load_handle: Arc<ResolvedLoadHandle>,
376}
377
378impl WeakHandle {
379 pub fn new(handle: Arc<ResolvedLoadHandle>) -> Self {
380 WeakHandle {
381 resolved_load_handle: handle,
382 }
383 }
384}
385
386impl ArtifactHandle for WeakHandle {
387 fn resolved_load_handle(&self) -> &Arc<ResolvedLoadHandle> {
388 &self.resolved_load_handle
389 }
390}
391
392std::thread_local!(static LOADER: std::cell::RefCell<Option<&'static dyn LoaderInfoProvider>> = RefCell::new(None));
393std::thread_local!(static REFOP_SENDER: std::cell::RefCell<Option<Sender<RefOp>>> = RefCell::new(None));
394
395pub struct SerdeContext;
398impl SerdeContext {
399 pub fn with_active<R>(f: impl FnOnce(&dyn LoaderInfoProvider, &Sender<RefOp>) -> R) -> R {
400 LOADER.with(|loader| {
402 REFOP_SENDER.with(|refop_sender| {
404 (f)(
405 *loader.borrow().as_ref().unwrap(),
406 refop_sender.borrow().as_ref().unwrap(),
407 )
408 })
413 })
416 }
417
418 pub fn with<T, F>(
419 loader: &dyn LoaderInfoProvider,
420 sender: Sender<RefOp>,
421 f: F,
422 ) -> T
423 where
424 F: FnOnce() -> T,
425 {
426 let loader_info_provider = unsafe {
430 std::mem::transmute::<&dyn LoaderInfoProvider, &'static dyn LoaderInfoProvider>(loader)
431 };
432
433 LOADER.with(|loader| {
434 *loader.borrow_mut() = Some(loader_info_provider);
435 let output = REFOP_SENDER.with(|refop_sender| {
436 *refop_sender.borrow_mut() = Some(sender);
437 let output = (f)();
438 *refop_sender.borrow_mut() = None;
439 output
440 });
441 *loader.borrow_mut() = None;
442 output
443 })
444
445 }
460}
461
462pub struct DummySerdeContext {
466 maps: RwLock<DummySerdeContextMaps>,
467 current: Mutex<DummySerdeContextCurrent>,
468 ref_sender: Sender<RefOp>,
469 handle_gen: AtomicU64,
470}
471
472struct DummySerdeContextMaps {
473 uuid_to_load: HashMap<ArtifactRef, LoadHandle>,
474 load_to_uuid: HashMap<LoadHandle, ArtifactRef>,
475}
476
477struct DummySerdeContextCurrent {
478 current_serde_dependencies: HashSet<ArtifactRef>,
479 current_serde_artifact: Option<ArtifactId>,
480}
481
482impl DummySerdeContext {
483 pub fn new() -> Self {
484 let (tx, _) = crossbeam_channel::unbounded();
485 Self {
486 maps: RwLock::new(DummySerdeContextMaps {
487 uuid_to_load: HashMap::default(),
488 load_to_uuid: HashMap::default(),
489 }),
490 current: Mutex::new(DummySerdeContextCurrent {
491 current_serde_dependencies: HashSet::new(),
492 current_serde_artifact: None,
493 }),
494 ref_sender: tx,
495 handle_gen: AtomicU64::new(1),
496 }
497 }
498}
499
500impl LoaderInfoProvider for DummySerdeContext {
501 fn resolved_load_handle(
502 &self,
503 artifact_ref: &ArtifactRef,
504 ) -> Option<Arc<ResolvedLoadHandle>> {
505 let mut maps = self.maps.write().unwrap();
506 let maps = &mut *maps;
507 let uuid_to_load = &mut maps.uuid_to_load;
508 let load_to_uuid = &mut maps.load_to_uuid;
509
510 let entry = uuid_to_load.entry(artifact_ref.clone());
511 let handle = entry.or_insert_with(|| {
512 let new_id = self.handle_gen.fetch_add(1, Ordering::Relaxed);
513 let handle = LoadHandle(new_id);
514 load_to_uuid.insert(handle, artifact_ref.clone());
515 handle
516 });
517
518 Some(Arc::new(ResolvedLoadHandle {
519 id: *handle,
520 direct_load_handle: AtomicU64::new(handle.0),
521 }))
522 }
523
524 fn artifact_id(
525 &self,
526 load: LoadHandle,
527 ) -> Option<ArtifactId> {
528 let maps = self.maps.read().unwrap();
529 let maybe_artifact = maps.load_to_uuid.get(&load).cloned();
530 if let Some(artifact_ref) = maybe_artifact.as_ref() {
531 let mut current = self.current.lock().unwrap();
532 if let Some(ref current_serde_id) = current.current_serde_artifact {
533 if ArtifactRef(*current_serde_id) != *artifact_ref
534 && *artifact_ref != ArtifactRef(ArtifactId::null())
535 {
536 current
537 .current_serde_dependencies
538 .insert(artifact_ref.clone());
539 }
540 }
541 }
542 if let Some(ArtifactRef(uuid)) = maybe_artifact {
543 Some(uuid)
544 } else {
545 None
546 }
547 }
548}
549pub struct DummySerdeContextHandle {
550 dummy: Arc<DummySerdeContext>,
551}
552
553impl Default for DummySerdeContextHandle {
554 fn default() -> Self {
555 DummySerdeContextHandle {
556 dummy: Arc::new(DummySerdeContext::new()),
557 }
558 }
559}
560
561impl DummySerdeContextHandle {
562 pub fn scope<'a, T, F: FnOnce() -> T>(
563 &self,
564 f: F,
565 ) -> T {
566 let sender = self.dummy.ref_sender.clone();
567 let loader = &*self.dummy;
568 SerdeContext::with(loader, sender, f)
569 }
570
571 pub fn resolve_ref(
572 &mut self,
573 artifact_ref: &ArtifactRef,
574 artifact: ArtifactId,
575 ) {
576 let new_ref = ArtifactRef(artifact);
577 let mut maps = self.dummy.maps.write().unwrap();
578 if let Some(handle) = maps.uuid_to_load.get(artifact_ref) {
579 let handle = *handle;
580 maps.load_to_uuid.insert(handle, new_ref.clone());
581 maps.uuid_to_load.insert(new_ref, handle);
582 }
583 }
584
585 pub fn begin_serialize_artifact(
587 &mut self,
588 artifact: ArtifactId,
589 ) {
590 let mut current = self.dummy.current.lock().unwrap();
591 if current.current_serde_artifact.is_some() {
592 panic!("begin_serialize_artifact when current_serde_artifact is already set");
593 }
594 current.current_serde_artifact = Some(artifact);
595 }
596
597 pub fn end_serialize_artifact(
599 &mut self,
600 _artifact: ArtifactId,
601 ) -> HashSet<ArtifactRef> {
602 let mut current = self.dummy.current.lock().unwrap();
603 if current.current_serde_artifact.is_none() {
604 panic!("end_serialize_artifact when current_serde_artifact is not set");
605 }
606 current.current_serde_artifact = None;
607 std::mem::take(&mut current.current_serde_dependencies)
608 }
609}
610
611fn serialize_handle<S>(
621 load: LoadHandle,
622 serializer: S,
623) -> Result<S::Ok, S::Error>
624where
625 S: ser::Serializer,
626{
627 SerdeContext::with_active(|loader, _| {
628 use ser::SerializeSeq;
629 let uuid_bytes: uuid::Bytes = *loader
630 .artifact_id(load)
631 .unwrap_or_default()
632 .as_uuid()
633 .as_bytes();
634 let mut seq = serializer.serialize_seq(Some(uuid_bytes.len()))?;
635 for element in &uuid_bytes {
636 seq.serialize_element(element)?;
637 }
638 seq.end()
639 })
640}
641impl<T> Serialize for Handle<T> {
642 fn serialize<S>(
643 &self,
644 serializer: S,
645 ) -> Result<S::Ok, S::Error>
646 where
647 S: ser::Serializer,
648 {
649 serialize_handle(self.handle_ref.resolved_load_handle.id, serializer)
650 }
651}
652impl Serialize for GenericHandle {
653 fn serialize<S>(
654 &self,
655 serializer: S,
656 ) -> Result<S::Ok, S::Error>
657 where
658 S: ser::Serializer,
659 {
660 serialize_handle(self.handle_ref.resolved_load_handle.id, serializer)
661 }
662}
663
664fn get_handle_ref(artifact_ref: ArtifactRef) -> (Arc<ResolvedLoadHandle>, Sender<RefOp>) {
665 SerdeContext::with_active(|loader, sender| {
666 let handle = if artifact_ref == ArtifactRef(ArtifactId::default()) {
667 ResolvedLoadHandle::new_null_handle()
668 } else {
669 loader
670 .resolved_load_handle(&artifact_ref)
671 .unwrap_or_else(|| panic!("Handle for ArtifactId {:?} was not present when deserializing a Handle. This indicates missing dependency metadata, and can be caused by dependency cycles.", artifact_ref))
672 };
673 (handle, sender.clone())
674 })
675}
676
677impl<'de, T> Deserialize<'de> for Handle<T> {
678 fn deserialize<D>(deserializer: D) -> Result<Handle<T>, D::Error>
679 where
680 D: de::Deserializer<'de>,
681 {
682 let artifact_ref = if deserializer.is_human_readable() {
683 deserializer.deserialize_any(ArtifactRefVisitor)?
684 } else {
685 deserializer.deserialize_seq(ArtifactRefVisitor)?
686 };
687 let (handle, sender) = get_handle_ref(artifact_ref);
688 Ok(Handle::new_internal(sender, handle))
689 }
690}
691
692impl<'de> Deserialize<'de> for GenericHandle {
693 fn deserialize<D>(deserializer: D) -> Result<GenericHandle, D::Error>
694 where
695 D: de::Deserializer<'de>,
696 {
697 let artifact_ref = if deserializer.is_human_readable() {
698 deserializer.deserialize_any(ArtifactRefVisitor)?
699 } else {
700 deserializer.deserialize_seq(ArtifactRefVisitor)?
701 };
702 let (handle, sender) = get_handle_ref(artifact_ref);
703 Ok(GenericHandle::new_internal(sender, handle))
704 }
705}
706
707struct ArtifactRefVisitor;
708
709impl<'de> de::Visitor<'de> for ArtifactRefVisitor {
710 type Value = ArtifactRef;
711
712 fn expecting(
713 &self,
714 formatter: &mut std::fmt::Formatter<'_>,
715 ) -> std::fmt::Result {
716 formatter.write_str("an array of 16 u8")
717 }
718
719 fn visit_newtype_struct<D>(
720 self,
721 deserializer: D,
722 ) -> Result<Self::Value, D::Error>
723 where
724 D: de::Deserializer<'de>,
725 {
726 deserializer.deserialize_seq(self)
727 }
728
729 fn visit_seq<A>(
730 self,
731 mut seq: A,
732 ) -> Result<Self::Value, A::Error>
733 where
734 A: de::SeqAccess<'de>,
735 {
736 use de::Error;
737 let mut uuid: [u8; 16] = Default::default();
738 for (i, uuid_byte) in uuid.iter_mut().enumerate() {
739 if let Some(byte) = seq.next_element::<u8>()? {
740 *uuid_byte = byte;
741 } else {
742 return Err(A::Error::custom(format!(
743 "expected byte at element {} when deserializing handle",
744 i
745 )));
746 }
747 }
748 if seq.next_element::<u8>()?.is_some() {
749 return Err(A::Error::custom(
750 "too many elements when deserializing handle",
751 ));
752 }
753 Ok(ArtifactRef(ArtifactId::from_uuid(Uuid::from_bytes(uuid))))
754 }
755
756 fn visit_str<E>(
757 self,
758 v: &str,
759 ) -> Result<Self::Value, E>
760 where
761 E: de::Error,
762 {
763 if let Ok(uuid) = Uuid::parse_str(v) {
764 Ok(ArtifactRef(ArtifactId::from_uuid(uuid)))
765 } else {
766 Err(E::custom(format!("failed to parse Handle string")))
767 }
768 }
769
770 fn visit_bytes<E>(
771 self,
772 v: &[u8],
773 ) -> Result<Self::Value, E>
774 where
775 E: de::Error,
776 {
777 if v.len() != 16 {
778 Err(E::custom(format!(
779 "byte array len == {}, expected {}",
780 v.len(),
781 16
782 )))
783 } else {
784 let mut a = <[u8; 16]>::default();
785 a.copy_from_slice(v);
786 Ok(ArtifactRef(ArtifactId::from_uuid(Uuid::from_bytes(a))))
787 }
788 }
789}
790
791pub trait TypedArtifactStorage<A> {
794 fn get<T: ArtifactHandle>(
804 &self,
805 handle: &T,
806 ) -> Option<&A>;
807}
808
809#[derive(Debug, Copy, Clone, PartialEq, Eq)]
810pub enum LoadState {
811 Unloaded,
814 WaitingForMetadata,
816 WaitingForDependencies,
818 WaitingForData,
820 Loading,
822 Loaded,
824}
825
826pub trait LoadStateProvider {
829 fn load_state(
830 &self,
831 load_handle: &Arc<ResolvedLoadHandle>,
832 ) -> LoadState;
833 fn artifact_id(
834 &self,
835 load_handle: &Arc<ResolvedLoadHandle>,
836 ) -> ArtifactId;
837}
838
839pub trait ArtifactHandle {
846 fn load_state<T: LoadStateProvider>(
856 &self,
857 loader: &T,
858 ) -> LoadState {
859 loader.load_state(self.resolved_load_handle())
860 }
861
862 fn artifact_id<T: LoadStateProvider>(
863 &self,
864 loader: &T,
865 ) -> ArtifactId {
866 loader.artifact_id(self.resolved_load_handle())
867 }
868
869 fn artifact<'a, T, S: TypedArtifactStorage<T>>(
875 &self,
876 storage: &'a S,
877 ) -> Option<&'a T>
878 where
879 Self: Sized,
880 {
881 storage.get(self)
882 }
883
884 fn downgrade(&self) -> WeakHandle {
889 WeakHandle::new(self.resolved_load_handle().clone())
890 }
891
892 fn resolved_load_handle(&self) -> &Arc<ResolvedLoadHandle>;
893
894 fn load_handle(&self) -> LoadHandle {
896 self.resolved_load_handle().id
897 }
898
899 fn direct_load_handle(&self) -> LoadHandle {
900 self.resolved_load_handle().direct_load_handle()
901 }
902}
903
904pub fn make_handle_within_serde_context<T>(uuid: ArtifactId) -> Handle<T> {
905 SerdeContext::with_active(|loader_info_provider, ref_op_sender| {
906 let load_handle = loader_info_provider
907 .resolved_load_handle(&ArtifactRef(uuid))
908 .unwrap();
909 Handle::<T>::new(ref_op_sender.clone(), load_handle)
910 })
911}