1#[derive(Copy, Clone, Debug, PartialEq, Eq)]
77 pub enum ICoWLockTypes
78 {
79 Atomic,
81
82 RwLock,
84 }
85
86impl fmt::Display for ICoWLockTypes
87{
88 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
89 {
90 match self
91 {
92 Self::Atomic =>
93 write!(f, "atomic"),
94 Self::RwLock =>
95 write!(f, "rwlock"),
96 }
97 }
98}
99
100#[derive(Copy, Clone, Debug, PartialEq, Eq)]
102pub enum ICoWError
103{
104 ExclusiveLockPending,
107
108 WouldBlock,
110}
111
112impl fmt::Display for ICoWError
113{
114 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
115 {
116 match self
117 {
118 Self::ExclusiveLockPending =>
119 write!(f, "already exlcusivly locked"),
120 Self::WouldBlock =>
121 write!(f, "cannot perform try operation due to blocking"),
122 }
123 }
124}
125
126
127#[cfg(all(target_has_atomic = "32", feature = "prefer_mutex"))]
129pub mod cow;
130
131#[cfg(any(not(target_has_atomic = "32"), not(feature = "prefer_mutex")))]
133pub mod cow_mutex;
134
135#[cfg(any(not(target_has_atomic = "32"), not(feature = "prefer_mutex")))]
136pub mod cow_refcell;
137
138use std::fmt;
139
140#[cfg(all(target_has_atomic = "32", feature = "prefer_mutex"))]
141pub use cow::{ICoW, ICoWRead, ICoWCopy, ICoWLock, ICoWWeak, ICoWWeakRead};
142
143#[cfg(any(not(target_has_atomic = "32"), not(feature = "prefer_mutex")))]
144pub use cow_mutex::{ICoW, ICoWRead, ICoWCopy, ICoWLock, ICoWWeak, ICoWWeakRead};
145
146#[cfg(all(not(target_has_atomic = "32"), feature = "prefer_mutex"))]
147compile_error!("target CPU does not support 'target_has_atomic'");
148
149pub trait ICowType
150{
151 fn get_lock_type() -> ICoWLockTypes;
152}
153
154#[cfg(test)]
155mod test
156{
157 use std::{sync::{LazyLock, mpsc}, thread, time::{Duration, Instant}};
158
159 use super::*;
160
161
162
163
164 #[test]
165 fn test_3()
166 {
167 #[derive(Debug, Clone)]
168 struct Test { s: String }
169
170 let icow = ICoW::new(Test{ s: "test".into() });
171
172 for _ in 0..10
173 {
174 let s = Instant::now();
175
176 let read0 = icow.read();
177
178 let e = s.elapsed();
179
180 println!("{:?}", e);
181 }
182
183 }
184
185 #[test]
186 fn test_33()
187 {
188 #[derive(Debug, Clone)]
189 struct Test { s: String };
190
191 let icow = ICoW::new(Test{ s: "test".into() });
192
193 let write_ex = icow.try_clone_copy_exclusivly().unwrap();
194
195 {
196 let write_ex_err = icow.try_clone_copy_exclusivly();
197 assert_eq!(write_ex_err.is_none(), true);
198 }
199
200 {
201 let write_ex_err = icow.try_clone_copy();
202 assert_eq!(write_ex_err.is_none(), true);
203 }
204 {
205 let read1 = icow.try_read();
206 assert_eq!(read1.is_none(), true);
207 }
208
209 drop(write_ex);
210
211 drop(icow);
212
213 }
214
215 #[test]
216 fn test_4()
217 {
218 #[derive(Debug, Clone)]
219 struct Test { s: u32 }
220
221 let icow = ICoW::new(Test{ s: 1 });
222
223 let read0 = icow.read();
224 let read1 = icow.read();
225
226 let mut excl_write = icow.try_clone_copy_exclusivly().unwrap();
227
228 excl_write.s = 5;
229
230
231 excl_write.commit();
232
233 assert_eq!(read0.s, 1);
234
235 let read3 = icow.read();
236 assert_eq!(read3.s, 5);
237
238 let mut writing = icow.try_clone_copy().unwrap();
239 writing.s = 4;
240
241 writing.commit().unwrap();
242
243 assert_eq!(read0.s, 1);
244 assert_eq!(read3.s, 5);
245
246 let read4 = icow.read();
247 assert_eq!(read4.s, 4);
248 }
249
250 #[test]
251 fn test_parking_lot_reader_wakeup()
252 {
253 #[derive(Debug, Clone)]
254 struct Test { s: u32 }
255
256 let icow = ICoW::new(Test{ s: 1 });
257
258 let read0 = icow.read();
259 let read2 = icow.read();
260
261 let c_icow = icow.clone();
262 let (se, rc) = mpsc::channel::<()>();
263 let handler0 =
264 std::thread::spawn(move ||
265 {
266 let mut lock0 = c_icow.try_clone_copy_exclusivly().unwrap();
267
268 se.send(()).unwrap();
269
270 lock0.s = 5;
271
272 std::thread::sleep(Duration::from_secs(2));
273
274 lock0.commit();
275 }
276 );
277
278 rc.recv().unwrap();
279
280 let s = Instant::now();
281
282 let read1 = icow.read();
283
284 let e = s.elapsed();
285
286 println!("thread wait: {:?}", e);
287
288 assert_eq!(e.as_secs(), 2);
289
290 handler0.join().unwrap();
291
292 drop(read0);
293 drop(read1);
294 drop(read2);
295 }
296
297 #[test]
298 fn text_9_exclu_lock_pend()
299 {
300 #[derive(Debug, Clone)]
301 struct Test { s: u32 }
302
303 let icow = ICoW::new(Test{ s: 1 });
304
305 let mut write0 = icow.clone_copy();
306 write0.s = 1222;
307
308 let c_icow = icow.clone();
309 let (se, rc) = mpsc::channel::<()>();
310 let handler0 =
311 std::thread::spawn(move ||
312 {
313 let mut lock0 =
314 loop
315 {
316 let res = c_icow.try_clone_copy_exclusivly();
317
318 if res.is_none() == true
319 {
320 continue;
321 }
322
323 break res.unwrap();
324 };
325
326 se.send(()).unwrap();
327
328 lock0.s = 5;
329
330 std::thread::sleep(Duration::from_secs(1));
331
332 lock0.commit();
333 }
334 );
335
336
337 rc.recv().unwrap();
338
339 let s = Instant::now();
340
341 let commit_res = write0.commit();
342 assert_eq!(commit_res.is_err(), true);
343 assert_eq!(commit_res.as_ref().err().unwrap().0, ICoWError::ExclusiveLockPending);
344 write0 = commit_res.err().unwrap().1;
345
346 write0.commit_blocking(true).unwrap();
347
348 let e = s.elapsed();
349
350 println!("thread wait: {:?}", e);
351
352 assert_eq!(e.as_secs(), 1);
353
354 handler0.join().unwrap();
355
356 return;
357 }
358
359 #[test]
360 fn test_5()
361 {
362 #[derive(Debug, Clone)]
363 struct Test { s: u32 }
364
365 let icow = ICoW::new(Test{ s: 1 });
366
367 let read0 = icow.read();
368 let read2 = icow.read();
369
370 let c_icow = icow.clone();
371
372 let (se, rc) = mpsc::channel::<()>();
373 let handler0 =
374 std::thread::spawn(move ||
375 {
376 let mut lock0 = c_icow.try_clone_copy_exclusivly().unwrap();
377
378 se.send(()).unwrap();
379
380 lock0.s = 5;
381
382 std::thread::sleep(Duration::from_micros(2));
383
384 lock0.commit();
385 }
386 );
387
388 rc.recv().unwrap();
389
390 let s = Instant::now();
391
392 let read1 = icow.read();
393
394 let e = s.elapsed();
395
396 println!("{:?}", e);
397
398
399 assert_eq!(read1.s, 5);
400 assert_eq!(read0.s, 1);
401
402 handler0.join().unwrap();
403
404 let weak0 = read0.weak();
405 let weak1 = read1.weak();
406
407 drop(read0);
408 drop(read1);
409
410 assert_eq!(weak0.upgrade().is_some(), true);
411 assert_eq!(weak1.upgrade().is_some(), true);
412
413 drop(read2);
414 assert_eq!(weak0.upgrade().is_none(), true);
415 assert_eq!(weak1.upgrade().is_some(), true);
416 }
417
418 #[test]
419 fn test_5_read_lock()
420 {
421 #[derive(Debug, Clone)]
422 struct Test { s: u32 }
423
424 let icow = ICoW::new(Test{ s: 1 });
425
426 let c_icow = icow.clone();
427
428 let (se, rc) = mpsc::channel::<()>();
429 let (se2, rc2) = mpsc::channel::<()>();
430 let handler0 =
431 std::thread::spawn(move ||
432 {
433 rc2.recv().unwrap();
434
435 let mut lock0 =
436 loop
437 {
438 let res = c_icow.try_clone_copy_exclusivly();
439
440 if res.is_none() == true
441 {
442 continue;
443 }
444
445 break res.unwrap();
446 };
447
448 se.send(()).unwrap();
449
450 lock0.s = 5;
451
452 lock0.commit();
453 }
454 );
455
456 let mut reads = Vec::<ICoWRead<'_, Test>>::with_capacity(20000);
457 let mut sent = false;
458
459 let s = Instant::now();
460
461 for i in 0..10000
462 {
463 let read0 = icow.read();
464 if read0.s == 5
465 {
466 println!("break at {}", i);
467 break;
468 }
469
470 reads.push(read0);
471
472 if sent == false
473 {
474 se2.send(());
475 sent = true;
476 }
477 }
478
479 let e = s.elapsed();
480
481 println!("{:?}", e);
482
483 assert_eq!(reads[0].s, 1);
484
485 handler0.join().unwrap();
486 }
487
488 #[test]
489 fn test_6()
490 {
491 #[derive(Debug, Clone)]
492 struct Test { s: u32 }
493
494 let icow = ICoW::new(Test{ s: 1 });
495
496 let read0 = icow.read();
497 let read2 = icow.read();
498
499 let c_icow = icow.clone();
500
501 let (se, rc) = mpsc::channel::<()>();
502 let handler0 =
503 std::thread::spawn(move ||
504 {
505 let read2 = c_icow.read();
506
507 let mut lock0 = c_icow.try_clone_copy_exclusivly().unwrap();
508
509 se.send(()).unwrap();
510
511 lock0.s = 5;
512
513 std::thread::sleep(Duration::from_nanos(50));
514 lock0.commit();
515
516 let read3 = c_icow.read();
517
518 assert_eq!(read2.s, 1);
519 assert_eq!(read3.s, 5);
520 }
521 );
522
523 rc.recv().unwrap();
524
525 for _ in 0..100000000
526 {
527 let read1 = icow.read();
528
529 if read1.s == 1
530 {
531 continue;
532 }
533 else
534 {
535 break;
536 }
537 }
538
539 let read1 = icow.read();
540 assert_eq!(read1.item.s, 5);
541
542 handler0.join().unwrap();
543
544 return;
545 }
546
547 #[test]
548 fn test_6_drop()
549 {
550 #[derive(Debug, Clone)]
551 struct Test { s: u32 }
552
553 let icow = ICoW::new(Test{ s: 1 });
554
555 let read0 = icow.read();
556 let read2 = icow.read();
557
558 let c_icow = icow.clone();
559
560 let (se, rc) = mpsc::channel::<()>();
561 let handler0 =
562 std::thread::spawn(move ||
563 {
564 let read2 = c_icow.read();
565
566 let mut lock0 = c_icow.try_clone_copy_exclusivly().unwrap();
567
568 rc.recv().unwrap();
569
570 lock0.s = 5;
571
572 std::thread::sleep(Duration::from_millis(1500));
573 lock0.commit();
574
575 let read3 = c_icow.read();
576
577 assert_eq!(read2.s, 1);
578 assert_eq!(read3.s, 5);
579 }
580 );
581
582 drop(read0);
583 let r2 = read2.clone_copy_into_inner();
584
585 se.send(()).unwrap();
586
587 drop(icow);
588
589 assert_eq!(r2.s, 1);
590
591 handler0.join().unwrap();
592
593 return;
594 }
595
596
597 #[test]
598 fn test_7()
599 {
600 #[derive(Debug, Clone)]
601 struct TestStruct { s: u32 }
602
603 impl TestStruct
604 {
605 fn new(s: u32) -> Self
606 {
607 return Self{ s: s };
608 }
609 }
610
611 static VAL: LazyLock<ICoW<TestStruct>> =
612 LazyLock::new(|| ICoW::new(TestStruct::new(1)));
613
614
615
616
617 let borrow1 = VAL.read();
618 assert_eq!(borrow1.item.s, 1);
619
620 let (mpsc_send, mpsc_rcv) = mpsc::channel::<u64>();
621 let (mpsc_send2, mpsc_rcv2) = mpsc::channel::<u64>();
622
623 let thread1 =
624 std::thread::spawn(move ||
625 {
626 for _ in 0..1000
627 {
628 let _ = mpsc_rcv2.recv();
629 let borrow1 = VAL.read();
630
631 let mut transaction = VAL.try_clone_copy_exclusivly().unwrap();
632
633 transaction.s = 5;
634
635
636
637 std::thread::sleep(Duration::from_nanos(1001));
638 transaction.commit();
639 let borrow2 = VAL.read();
640
641
642 assert_eq!(borrow1.item.s, 1);
643
644 assert_eq!(borrow2.item.s, 5);
645
646 let _ = mpsc_send.send(1);
647 }
648 }
649 );
650
651
652
653 for x in 0..1000
654 {
655 println!("{}", x);
656 mpsc_send2.send(1).unwrap();
657 let _ = mpsc_rcv.recv();
658
659 let borrow1 = VAL.read();
660 assert_eq!(borrow1.s, 5);
661
662 let mut transaction = VAL.try_clone_copy_exclusivly().unwrap();
663 transaction.s = 1;
664 transaction.commit();
665
666 let borrow1 = VAL.read();
667 assert_eq!(borrow1.s, 1);
668
669 }
670
671
672
673 thread1.join().unwrap();
674
675
676 }
677
678
679 #[test]
680 fn test_8()
681 {
682 #[derive(Debug, Clone)]
683 struct Test { s: u32 }
684
685 let icow = ICoW::new(Test{ s: 1 });
686
687 for _ in 0..20
688 {
689 let read0 = icow.read();
690 let read2 = icow.read();
691
692 let c_icow = icow.clone();
693
694 let handler0 =
696 std::thread::spawn(move ||
697 {
698 let read2 = c_icow.read();
699
700 let mut lock0 = c_icow.clone_copy();
701
702 lock0.s = 5;
705
706 std::thread::sleep(Duration::from_micros(1));
707 lock0.commit_blocking(false).unwrap();
708
709 let read3 = c_icow.read();
710
711 assert_eq!(read2.s, 1);
712 assert_eq!(read3.s, 5);
713 }
714 );
715
716 for i in 0..1000000000
719 {
720 let read1 = icow.read();
721
722 if read1.s == 1
723 {
724 continue;
725 }
726 else
727 {
728 println!("{}", i);
729 break;
730 }
731 }
732
733 let read1 = icow.read();
734 assert_eq!(read1.s, 5);
735
736 handler0.join().unwrap();
737
738 let mut lock0 = icow.try_clone_copy().unwrap();
739 lock0.s = 1;
740 lock0.commit_blocking(false).unwrap();
741 }
742
743 return;
744 }
745
746 #[test]
747 fn test_9()
748 {
749 #[derive(Debug, Clone)]
750 struct Test { s: u32 }
751
752 let icow = ICoW::new(Test{ s: 1 });
753
754 let weak_reader = icow.reader();
755
756 let weak_r0 = weak_reader.aquire().unwrap();
757
758 assert_eq!(weak_r0.s, 1);
759
760 drop(weak_r0);
761
762 let mut copy1 = icow.clone_copy();
763 copy1.s = 8;
764 copy1.commit_blocking(true).unwrap();
765
766 let weak_r0 = weak_reader.aquire().unwrap();
767
768 assert_eq!(weak_r0.s, 8);
769
770 drop(weak_r0);
771
772 drop(icow);
775
776 let weak_r0 = weak_reader.aquire();
777 assert_eq!(weak_r0.is_none(), true);
778
779 }
780
781 #[test]
782 fn test_10()
783 {
784 #[derive(Debug, Clone)]
785 struct Test { s: u32 }
786
787 let icow = ICoW::new(Test{ s: 1 });
788
789 let weak_reader = icow.reader();
790
791 let (tx, rx) = mpsc::channel::<()>();
792 let (tx2, rx2) = mpsc::channel::<()>();
793
794 let thread_hndl =
795 thread::spawn(move ||
796 {
797 let weak_r0 = weak_reader.aquire().unwrap();
798
799 assert_eq!(weak_r0.s, 1);
800
801 drop(weak_r0);
802
803 tx.send(()).unwrap();
804
805 let _ = rx2.recv().unwrap();
807
808 let weak_r0 = weak_reader.aquire().unwrap();
809
810 assert_eq!(weak_r0.item_updated(), true);
811 assert_eq!(weak_r0.s, 8);
812
813 drop(weak_r0);
814
815 tx.send(()).unwrap();
816 let _ = rx2.recv().unwrap();
818
819 let weak_r0 = weak_reader.aquire();
821 assert_eq!(weak_r0.is_none(), true);
822 }
823 );
824
825 let _ = rx.recv().unwrap();
826
827 let mut copy1 = icow.clone_copy();
828 copy1.s = 8;
829 copy1.commit_blocking(true).unwrap();
830
831 tx2.send(()).unwrap();
832 let _ = rx.recv().unwrap();
833
834 drop(icow);
837
838 tx2.send(()).unwrap();
839
840 thread_hndl.join().unwrap();
841
842 return;
843
844 }
845}