instance_copy_on_write/
cow_mutex.rs

1/*-
2 * instance-copy-on-write - a synchronization primitive based on copy-on-write.
3 * 
4 * Copyright (C) 2025 Aleksandr Morozov alex@
5 * 
6 * The scram-rs crate can be redistributed and/or modified
7 * under the terms of either of the following licenses:
8 *
9 *   1. the Mozilla Public License Version 2.0 (the “MPL”) OR
10 *                     
11 *   2. EUROPEAN UNION PUBLIC LICENCE v. 1.2 EUPL © the European Union 2007, 2016
12 */
13
14#[cfg(test)]
15use std::sync::Weak;
16use std::{fmt, ops::{Deref, DerefMut}, sync::{Arc, RwLock, RwLockWriteGuard, TryLockError}};
17
18use crossbeam_utils::Backoff;
19
20use crate::{ICoWError, ICoWLockTypes};
21
22
23/// A read only guard. Implements [Deref] only. The guarded value is valid
24/// all the time, even if the inner value was updated. The updated value
25/// will not be visible in the current instance until `re-read` is
26/// performed.
27#[derive(Debug)]
28pub struct ICoWRead<'read, ITEM: fmt::Debug + Send>
29{
30    /// Guarded value.
31    item: Arc<ITEM>,
32
33    /// A bind to base.
34    bind: &'read ICoW<ITEM>
35}
36
37#[cfg(test)]
38impl<'read, ITEM: fmt::Debug + Send> ICoWRead<'read, ITEM>
39{
40    fn weak(&self) -> Weak<ITEM>
41    {
42        return Arc::downgrade(&self.item);
43    }
44}
45
46impl<'read, ITEM: fmt::Debug + Send> Deref for ICoWRead<'read, ITEM>
47{
48    type Target = ITEM;
49
50    fn deref(&self) -> &Self::Target
51    {
52        return &self.item;
53    }
54}
55
56
57/// A write-guard which holds new value to which the new values are written. And
58/// previous value too. This type of guard is not exclusive, so it does not prevent
59/// multiple CoW operations. Normally, if some object which may be written 
60/// simultaniously i.e lost connection to remote server and reconnect is required,
61/// the `exclusive` lock would be more desirable.
62#[derive(Debug)]
63pub struct ICoWCopy<'copy, ITEM: fmt::Debug + Send>
64{
65    /// A reference to previous value
66    prev_item: ICoWRead<'copy, ITEM>,
67    
68    /// A freshly createc/copied/clonned item
69    new_item: ITEM,
70
71    /// A reference to base to avoid Send.
72    inst: &'copy ICoW<ITEM>
73}
74
75impl<'copy, ITEM: fmt::Debug + Send> Deref for ICoWCopy<'copy, ITEM>
76{
77    type Target = ITEM;
78
79    fn deref(&self) -> &Self::Target
80    {
81        return &self.new_item;
82    }
83}
84
85impl<'copy, ITEM: fmt::Debug + Send> DerefMut for ICoWCopy<'copy, ITEM>
86{
87    fn deref_mut(&mut self) -> &mut Self::Target
88    {
89        return &mut self.new_item
90    }
91}
92
93impl<'copy, ITEM: fmt::Debug + Send> ICoWCopy<'copy, ITEM>
94{
95    /// Returns a reference to previous value. To access modified version use
96    /// [Deref] or [DerefMut].
97    pub 
98    fn prev_val(&self) -> &ITEM
99    {
100        return &self.prev_item;
101    }
102
103    /// Commits the changes made in the guarded variable. A non-blocking
104    /// function. It will not block the thread completly and returns the
105    /// [ICoWError::WouldBlock] if attempt to grab the pointer atomically 
106    /// fails.
107    /// 
108    /// # Returns
109    /// 
110    /// The [Result::Err] is returned with:
111    /// 
112    /// * `0` - [ICoWError] with the error type.
113    /// 
114    /// * `1` - [ICoWCopy] instance itself.
115    /// 
116    /// Error types [ICoWError]:
117    /// 
118    /// * [ICoWError::ExclusiveLockPending] - if exclusivly locked from another thread.
119    /// 
120    /// * [ICoWError::WouldBlock] - `atomic only!` if "exponential backoff has completed and blocking the thread is advised".
121    pub 
122    fn commit(self) -> Result<(), (ICoWError, Self)>
123    {
124        let write_lock = 
125            self
126                .inst
127                .inner
128                .try_write();
129                //.unwrap_or_else(|e| e.into_inner());
130
131        let mut lock = 
132            match write_lock
133            {
134                Ok(lock) => 
135                    lock,
136                Err(TryLockError::Poisoned(lock_err)) => 
137                    lock_err.into_inner(),
138                Err(TryLockError::WouldBlock) => 
139                    return Err((ICoWError::ExclusiveLockPending, self)),
140            };
141
142        *lock = Arc::new(self.new_item);
143
144        return Ok(());
145    }
146    
147}
148
149/// A write-guard which holds new value to which the new values are written. And
150/// previous value too. This type of guard is exclusive, so multiple
151/// CoW operations **CANNOT** be performed in parallel which is good for instance 
152/// update without racing. The readers are also waiting until the changes are 
153/// commited.
154#[derive(Debug)]
155pub struct ICoWLock<'lock, ITEM: fmt::Debug + Send>
156{
157    /// An exclusive lock in the previous value.
158    prev_item: RwLockWriteGuard<'lock, Arc<ITEM>>,
159
160    /// A freshly createc/copied/clonned item
161    item: ITEM,
162
163    /// A reference to base to avoid Send.
164    inst: &'lock ICoW<ITEM>
165}
166
167impl<'lock, ITEM: fmt::Debug + Send> ICoWLock<'lock, ITEM>
168{
169    /// Returns a reference to previous value. To access modified version use
170    /// [Deref] or [DerefMut].
171    pub 
172    fn prev_val(&self) -> &ITEM
173    {
174        return self.prev_item.as_ref();
175    }
176
177    /// Commits the changes made in the guarded variable.
178    /// 
179    /// # Returns
180    /// 
181    /// Always returns [Result::Ok], but the `atomic` realization
182    /// would return [Result::Err] if:
183    /// 
184    /// > The [Result::Err] is retruned if race condition happens i.e when 
185    /// > updating the inner atomic ptr fails because someone have already 
186    /// > changed the value.
187    #[inline]
188    pub 
189    fn commit(mut self) -> Result<(), Self>
190    {
191        *self.prev_item = Arc::new(self.item);
192
193        return Ok(());
194    }
195}
196
197impl<'lock, ITEM: fmt::Debug + Send> Deref for ICoWLock<'lock, ITEM>
198{
199    type Target = ITEM;
200
201    fn deref(&self) -> &Self::Target
202    {
203        return &self.item;
204    }
205}
206
207impl<'lock, ITEM: fmt::Debug + Send> DerefMut for ICoWLock<'lock, ITEM>
208{
209    fn deref_mut(&mut self) -> &mut Self::Target
210    {
211        return &mut self.item
212    }
213}
214
215/// A main structure which implements CoW approach based on [RwLock] for the
216/// multithreading syncing.  The object stored inside can be read directly, but 
217/// modifying the `inner` value is performed using `CoW` copy-on-write approach. 
218/// 
219/// The inner value must either [Copy], [Clone], [Default], or provide 
220/// new value manually. The copied value is modified and stored back either
221/// shared or exclusive method. The exclusive lock prevents other CoW operations
222/// guaranteeing the uniq write access.
223/// 
224/// ```ignore
225/// #[derive(Debug, Clone)]
226/// struct TestStruct { s: u32 }
227/// 
228/// let cow_val = ICoW::new(TestStruct{ s: 2 });
229/// 
230/// // read
231/// let read0 = cow_val.read().unwrap();
232/// // ...
233/// drop(read0);
234/// 
235/// // write new non-exclusivly
236/// let mut write0 = cow_val.try_clone().unwrap();
237/// write0.s = 3;
238/// 
239/// write0.commit().unwrap();
240/// 
241/// // write new exclusivly
242/// let mut write0 = cow_val.try_clone_exclusivly().unwrap();
243/// write0.s = 3;
244/// 
245/// write0.commit().unwrap(); 
246/// 
247/// ```
248#[derive(Debug)]
249pub struct ICoW<ITEM: fmt::Debug + Send>
250{
251    /// A rwlock protected CoW.
252    inner: RwLock<Arc<ITEM>>
253}
254
255impl<ITEM: fmt::Debug + Send> ICoW<ITEM>
256{
257    /// Initalizes a new instance.
258    pub 
259    fn new(item: ITEM) -> Self
260    {
261        return Self{ inner: RwLock::new(Arc::new(item))}
262    }
263
264    /// Returns the syncing meachanism.
265    pub 
266    fn get_lock_type() -> ICoWLockTypes
267    {
268        return ICoWLockTypes::RwLock;
269    }
270}
271
272impl<ITEM: fmt::Debug + Send> ICoW<ITEM>
273{
274    /// Attempts to read the inner value returning the guard. This function 
275    /// blocks the current thread until the value becomes available. This
276    /// can happen if exclusive copy-on-write is in progress.
277    /// 
278    /// # Returns 
279    /// 
280    /// An instance with clonned reference is returned.
281    pub 
282    fn read(&self) -> ICoWRead<'_, ITEM>
283    {
284        let lock = 
285            self
286                .inner
287                .read()
288                .unwrap_or_else(|e| e.into_inner());
289
290        return ICoWRead{ item: lock.clone(), bind: self };
291    }
292
293    /// Attempts to read the inner value, returning the read guard in case of success. 
294    /// This function does not block the current thread until the value becomes available. 
295    /// This function fails if exclusive copy-on-write is in progress.
296    /// 
297    /// But, this fucntion would block the thread until the [Backoff] reports
298    /// that it is recomended to park the thread.
299    /// 
300    /// # Returns 
301    /// 
302    /// A [Option] is retrurned. The [Option::None] is returned if operation
303    /// would block for a long time. 
304    pub 
305    fn try_read(&self) -> Option<ICoWRead<'_, ITEM>>
306    {
307        let lock_res = 
308            self
309                .inner
310                .try_read();
311
312        match lock_res 
313        {
314            Ok(lock) => 
315            {
316                return Some(ICoWRead{ item: lock.clone(), bind: self });
317            },
318            Err(TryLockError::WouldBlock)=>
319            {
320                return None;
321            },
322            Err(TryLockError::Poisoned(lock)) =>
323            {
324                return Some(ICoWRead{ item: lock.into_inner().clone(), bind: self });
325            }
326        }
327    }
328
329    /// Attempts to grab the **exclusive** Copy-on-Write to prevent duplicate
330    /// writing.
331    /// 
332    /// Non-blocking function i.e returns if it fails to acquire the
333    /// clone before some deadline.
334    /// 
335    /// # Returns
336    /// 
337    /// An [Option] is returned where the [Option::None] is returned if
338    /// an exclusive CoW lock have already been issued.
339    pub 
340    fn try_new_exclusivly(&self, new_item: ITEM) -> Option<ICoWLock<'_, ITEM>>
341    {
342        let write_lock =  
343            match self.inner.try_write()
344            {
345                Ok(r) => r,
346                Err(TryLockError::Poisoned(e)) => e.into_inner(),
347                Err(TryLockError::WouldBlock) =>
348                    return None
349            };
350        
351        return Some(
352            ICoWLock{ prev_item: write_lock, item: new_item, inst: self }
353        );
354    }
355
356    /// Attempts to update old value to new value for the inner.
357    /// 
358    /// Non-blocking function i.e returns if it fails to acquire the
359    /// clone before some deadline. And does not block if the write access
360    /// is not available now due to the exclusive lock pending.
361    /// 
362    /// Does not return guard. Updates the value in-place.
363    /// 
364    /// # Returns
365    /// 
366    /// A [Result] is returned where the [Result::Err] is returned with:
367    /// 
368    /// * [ICoWError::ExclusiveLockPending] - if exclsive write already pending.
369    /// 
370    /// * errors which are returned by [ICoWCopy::commit()].
371    pub 
372    fn try_new_inplace(&self, new_item: ITEM) -> Result<(), (ICoWError, ITEM)>
373    {
374        if let Some(read) = self.try_read()
375        {
376            let ret = 
377                ICoWCopy
378                { 
379                    prev_item: read, 
380                    new_item: new_item, 
381                    inst: self 
382                };
383
384            return ret.commit().map_err(|e| (e.0, e.1.new_item));
385        }
386        else
387        {
388            return Err((ICoWError::WouldBlock, new_item));
389        }
390    }
391
392    /// Attempts to update old value to new value for the inner
393    /// **exclusively**.
394    /// 
395    /// Non-blocking function i.e returns if it fails to acquire the
396    /// clone before some deadline.
397    /// 
398    /// Does not return guard. Updates the value in-place.
399    /// 
400    /// # Returns
401    /// 
402    /// A [Result] is returned where the [Result::Err] is returned with:
403    /// 
404    /// * [ICoWError::ExclusiveLockPending] - if exclsive write already pending.
405    /// 
406    /// * [ICoWError::AlreadyUpdated] - if duplicate write operation attempt.
407    /// 
408    /// * [ICoWError::RaceCondition] - a race condition detected during update.
409    /// 
410    /// * errors which are returned by [ICoWCopy::commit()].
411    pub 
412    fn try_new_exclusivly_inplace(&self, new_item: ITEM) -> Result<(), (ICoWError, ITEM)>
413    {
414        
415        let write_lock =  
416            match self.inner.try_write()
417            {
418                Ok(lock) => 
419                    lock,
420                Err(TryLockError::Poisoned(e)) => 
421                    e.into_inner(),
422                Err(TryLockError::WouldBlock) =>
423                    return Err((ICoWError::ExclusiveLockPending, new_item))
424            };
425        
426        let ret =
427            ICoWLock{ prev_item: write_lock, item: new_item, inst: self };
428        
429        return Ok(ret.commit().unwrap());
430    }
431}
432
433impl<ITEM: fmt::Debug + Send + Copy> ICoW<ITEM>
434{
435    /// Performs the copy of the inner value for writing.
436    /// 
437    /// Blocking function i.e always retruns the result.
438    /// 
439    /// # Returns
440    /// 
441    /// An [ICoWCopy] is returned.
442    pub 
443    fn copy(&self) -> ICoWCopy<'_, ITEM>
444    {
445        let read = self.read();
446
447        let new_item = *read.item.as_ref();
448
449        let ret = 
450            ICoWCopy
451            { 
452                prev_item: read, 
453                new_item: new_item, 
454                inst: self 
455            };
456
457        return ret;
458    }
459
460    /// Attempts to perform the copy of the inner value for writing.
461    /// 
462    /// Non-blocking function i.e returns if it fails to acquire the
463    /// copy before some deadline.
464    /// 
465    /// # Returns
466    /// 
467    /// An [Option] is returned where the [Option::None] is returned if
468    /// it failed.
469    pub 
470    fn try_copy(&self) -> Option<ICoWCopy<'_, ITEM>>
471    {
472        let read = self.try_read()?;
473
474        let new_item = *read.item.as_ref();
475
476        let ret = 
477            ICoWCopy
478            { 
479                prev_item: read, 
480                new_item: new_item, 
481                inst: self 
482            };
483
484        return Some(ret);
485    }
486
487    /// Attempts to perform the copy of the inner value for 
488    /// **exclusive** writing.
489    /// 
490    /// Non-blocking function i.e returns if it fails to acquire the
491    /// copy before some deadline.
492    /// 
493    /// # Returns
494    /// 
495    /// An [Option] is returned where the [Option::None] is returned if
496    /// an exclusive CoW lock have already been issued.
497    pub 
498    fn try_copy_exclusivly(&self) -> Option<ICoWLock<'_, ITEM>>
499    {
500
501       let write_lock =  
502            match self.inner.try_write()
503            {
504                Ok(r) => r,
505                Err(TryLockError::Poisoned(e)) => e.into_inner(),
506                Err(TryLockError::WouldBlock) =>
507                    return None
508            };
509        
510        let new_item = *write_lock.as_ref(); 
511        
512        return Some(
513            ICoWLock{ prev_item: write_lock, item: new_item, inst: self }
514        );
515    }
516}
517
518impl<ITEM: fmt::Debug + Send + Clone> ICoW<ITEM>
519{
520    /// Attempts to perform the clone of the inner value for writing.
521    /// 
522    /// Blocking function i.e always retruns the result.
523    /// 
524    /// # Returns
525    /// 
526    /// An [ICoWCopy] is returned.
527    pub 
528    fn clone(&self) -> ICoWCopy<'_, ITEM>
529    {
530        let read = self.read();
531
532        let new_item = read.item.as_ref().clone();
533
534        let ret = 
535            ICoWCopy
536            { 
537                prev_item: read, 
538                new_item: new_item, 
539                inst: self 
540            };
541
542        return ret;
543    }
544
545    /// Attempts to perform the clone of the inner value for writing.
546    /// 
547    /// Non-blocking function i.e returns if it fails to acquire the
548    /// clone before some deadline.
549    /// 
550    /// # Returns
551    /// 
552    /// An [Option] is returned where the [Option::None] is returned if
553    /// it failed.
554    pub 
555    fn try_clone(&self) -> Option<ICoWCopy<'_, ITEM>>
556    {
557        let read = self.try_read()?;
558
559        let new_item = read.item.as_ref().clone();
560
561        let ret = 
562            ICoWCopy
563            { 
564                prev_item: read, 
565                new_item: new_item, 
566                inst: self 
567            };
568
569        return Some(ret);
570    }
571
572    /// Attempts to perform the clone of the inner value for 
573    /// **exclusive** writing.
574    /// 
575    /// Non-blocking function i.e returns if it fails to acquire the
576    /// clone before some deadline.
577    /// 
578    /// # Returns
579    /// 
580    /// An [Option] is returned where the [Option::None] is returned if
581    /// an exclusive CoW lock have already been issued.
582    pub 
583    fn try_clone_exclusivly(&self) -> Option<ICoWLock<'_, ITEM>>
584    {
585        
586        let write_lock =  
587            match self.inner.try_write()
588            {
589                Ok(r) => r,
590                Err(TryLockError::Poisoned(e)) => e.into_inner(),
591                Err(TryLockError::WouldBlock) =>
592                    return None
593            };
594        
595        let new_item = write_lock.as_ref().clone();
596        
597        return Some(
598            ICoWLock{ prev_item: write_lock, item: new_item, inst: self }
599        );
600    }
601}
602
603impl<ITEM: fmt::Debug + Send + Default> ICoW<ITEM>
604{
605    /// Construct the guard from the [Default] of the inner value for writing.
606    /// 
607    /// Blocking function i.e always retruns the result.
608    /// 
609    /// # Returns
610    /// 
611    /// An [Option] is returned where the [Option::None] is returned if
612    /// it failed.
613    pub 
614    fn from_default(&self) -> ICoWCopy<'_, ITEM>
615    {
616        let read = self.read();
617
618        let new_item = ITEM::default();
619
620        let ret = 
621            ICoWCopy
622            { 
623                prev_item: read, 
624                new_item: new_item, 
625                inst: self 
626            };
627
628        return ret;
629    }
630
631    /// Attempts to init default of the inner value for writing.
632    /// 
633    /// Non-blocking function i.e returns if it fails to acquire the
634    /// clone before some deadline.
635    /// 
636    /// # Returns
637    /// 
638    /// An [Option] is returned where the [Option::None] is returned if
639    /// it failed.
640    pub 
641    fn try_default(&self) -> Option<ICoWCopy<'_, ITEM>>
642    {
643        let read = self.try_read()?;
644
645        let new_item = ITEM::default();
646
647        let ret = 
648            ICoWCopy
649            { 
650                prev_item: read, 
651                new_item: new_item, 
652                inst: self 
653            };
654
655        return Some(ret);
656    }
657      
658
659    /// Attempts to init default of the inner value for 
660    /// **exclusive** writing.
661    /// 
662    /// Non-blocking function i.e returns if it fails to acquire the
663    /// clone before some deadline.
664    /// 
665    /// # Returns
666    /// 
667    /// An [Option] is returned where the [Option::None] is returned if
668    /// an exclusive CoW lock have already been issued.
669    pub 
670    fn try_default_exclusivly(&self) -> Option<ICoWLock<'_, ITEM>>
671    {
672        let write_lock =  
673            match self.inner.try_write()
674            {
675                Ok(r) => r,
676                Err(TryLockError::Poisoned(e)) => e.into_inner(),
677                Err(TryLockError::WouldBlock) =>
678                    return None
679            };
680        
681        let new_item = ITEM::default();
682        
683        return Some(
684            ICoWLock{ prev_item: write_lock, item: new_item, inst: self }
685        );
686    }
687}
688
689
690#[cfg(test)]
691mod test
692{
693    use std::{sync::{mpsc, LazyLock}, time::{Duration, Instant}};
694
695    use super::*;
696
697
698
699
700    #[test]
701    fn test_3()
702    {
703        #[derive(Debug, Clone)]
704        struct Test { s: String };
705
706        let icow = ICoW::new(Test{ s: "test".into() });
707
708        for _ in 0..10
709        {
710            let s = Instant::now();
711
712            let read0 = icow.read();
713
714            let e = s.elapsed();
715
716            println!("{:?}", e);
717        }
718
719    }
720
721    #[test]
722    fn test_33()
723    {
724        #[derive(Debug, Clone)]
725        struct Test { s: String };
726
727        let icow = ICoW::new(Test{ s: "test".into() });
728
729        let write_ex = icow.try_clone_exclusivly().unwrap();
730
731        {
732        let write_ex_err = icow.try_clone_exclusivly();
733        assert_eq!(write_ex_err.is_none(), true);
734        }
735
736        let write_ex_err = icow.try_clone();
737        assert_eq!(write_ex_err.is_none(), true);
738
739        let read1 = icow.try_read();
740        assert_eq!(read1.is_none(), true);
741
742        drop(write_ex);
743
744        drop(icow);
745
746    }
747
748    #[test]
749    fn test_4()
750    {
751        #[derive(Debug, Clone)]
752        struct Test { s: u32 }
753
754        let icow = ICoW::new(Test{ s: 1 });
755
756        let read0 = icow.read();
757        let read1 = icow.read();
758
759        let mut excl_write = icow.try_clone_exclusivly().unwrap();
760
761        excl_write.item.s = 5;
762
763
764        excl_write.commit().unwrap();
765
766        assert_eq!(read0.item.s, 1);
767
768        let read3 = icow.read();
769        assert_eq!(read3.item.s, 5);
770
771        let mut writing = icow.try_clone().unwrap();
772        writing.s = 4;
773
774        writing.commit().unwrap();
775
776        assert_eq!(read0.item.s, 1);
777        assert_eq!(read3.item.s, 5);
778
779        let read4 = icow.read();
780        assert_eq!(read4.s, 4);
781    }
782
783    #[test]
784    fn test_5()
785    {
786        #[derive(Debug, Clone)]
787        struct Test { s: u32 }
788
789        let icow = Arc::new(ICoW::new(Test{ s: 1 }));
790
791        let read0 = icow.read();
792        let read2 = icow.read();
793        
794        let c_icow = icow.clone();
795
796        let (se, rc) = mpsc::channel::<()>();
797        let handler0 = 
798            std::thread::spawn(move || 
799                {
800                    let mut lock0 = c_icow.try_clone_exclusivly().unwrap();
801
802                    se.send(()).unwrap();
803
804                    lock0.item.s = 5;
805
806                    std::thread::sleep(Duration::from_micros(2));
807
808                    lock0.commit().unwrap();
809                }
810            );
811
812        rc.recv().unwrap();
813
814        let s = Instant::now();
815
816        let read1 = icow.read();
817        
818        let e = s.elapsed();
819
820        println!("{:?}", e);
821
822        
823        assert_eq!(read1.item.s, 5);
824        assert_eq!(read0.item.s, 1);
825
826        handler0.join().unwrap();
827
828        let weak0 = read0.weak();
829        let weak1 = read1.weak();
830
831        drop(read0);
832        drop(read1);
833
834        assert_eq!(weak0.upgrade().is_some(), true);
835        assert_eq!(weak1.upgrade().is_some(), true);
836
837        drop(read2);
838        assert_eq!(weak0.upgrade().is_none(), true);
839        assert_eq!(weak1.upgrade().is_some(), true);
840    }
841
842
843    #[test]
844    fn test_6()
845    {
846        #[derive(Debug, Clone)]
847        struct Test { s: u32 }
848
849        let icow = Arc::new(ICoW::new(Test{ s: 1 }));
850
851        let read0 = icow.read();
852        let read2 = icow.read();
853        
854        let c_icow = icow.clone();
855
856        let (se, rc) = mpsc::channel::<()>();
857        let handler0 = 
858            std::thread::spawn(move || 
859                {
860                    let read2 = c_icow.read();
861
862                    let mut lock0 = c_icow.try_clone_exclusivly().unwrap();
863
864                    se.send(()).unwrap();
865
866                    lock0.item.s = 5;
867
868                    std::thread::sleep(Duration::from_nanos(50));
869                    lock0.commit().unwrap();
870
871                    let read3 = c_icow.read();
872
873                    assert_eq!(read2.item.s, 1);
874                    assert_eq!(read3.item.s, 5);
875                }
876            );
877
878        rc.recv().unwrap();
879
880        for _ in 0..100000000
881        {
882            let read1 = icow.read();
883
884            if read1.item.s == 1
885            {
886                continue;
887            }
888            else
889            {
890                break;
891            }
892        }
893
894        let read1 = icow.read();
895        assert_eq!(read1.item.s, 5);
896
897        handler0.join().unwrap();
898
899        return;
900    }
901
902
903    #[test]
904    fn test_7()
905    {
906        #[derive(Debug, Clone)]
907        struct TestStruct { s: u32 }
908
909        impl TestStruct
910        {
911            fn new(s: u32) -> Self
912            {
913                return Self{ s: s };
914            }
915        }
916
917        static VAL: LazyLock<ICoW<TestStruct>> = 
918            LazyLock::new(|| ICoW::new(TestStruct::new(1))); 
919        
920
921        
922        
923            let borrow1 = VAL.read();
924            assert_eq!(borrow1.item.s, 1);
925
926            let (mpsc_send, mpsc_rcv) = mpsc::channel::<u64>();
927            let (mpsc_send2, mpsc_rcv2) = mpsc::channel::<u64>();
928
929            let thread1 = 
930                std::thread::spawn(move ||
931                    {
932                        for _ in 0..1000
933                        {
934                            let _ = mpsc_rcv2.recv();
935                            let borrow1 = VAL.read();
936
937                            let mut transaction = VAL.try_clone_exclusivly().unwrap();
938
939                            transaction.item.s = 5;
940
941                            
942
943                            std::thread::sleep(Duration::from_nanos(1001));
944                            transaction.commit().unwrap();
945
946                            let borrow2 = VAL.read();
947                            
948
949                            assert_eq!(borrow1.item.s, 1);
950
951                            assert_eq!(borrow2.item.s, 5);
952
953                            let _ = mpsc_send.send(1);
954                        }
955                    }
956                );
957            
958            
959
960            for x in 0..1000
961            {
962                println!("{}", x);
963                mpsc_send2.send(1).unwrap();
964                let _ = mpsc_rcv.recv();
965
966                let borrow1 = VAL.read();
967                assert_eq!(borrow1.item.s, 5);
968
969                let mut transaction = VAL.try_clone_exclusivly().unwrap();
970                transaction.item.s = 1;
971                transaction.commit().unwrap();
972
973                let borrow1 = VAL.read();
974                assert_eq!(borrow1.item.s, 1);
975                
976            }
977            
978            
979
980            thread1.join().unwrap();
981
982            
983    }
984
985
986    #[test]
987    fn test_8()
988    {
989        #[derive(Debug, Clone)]
990        struct Test { s: u32 }
991
992        let icow = Arc::new(ICoW::new(Test{ s: 1 }));
993
994        for _ in 0..20
995        {
996            let read0 = icow.read();
997            let read2 = icow.read();
998            
999            let c_icow = icow.clone();
1000
1001            //let (se, rc) = mpsc::channel::<()>();
1002            let handler0 = 
1003                std::thread::spawn(move || 
1004                    {
1005                        let read2 = c_icow.read();
1006
1007                        let mut lock0 = c_icow.try_clone().unwrap();
1008
1009                        //se.send(()).unwrap();
1010
1011                        lock0.s = 5;
1012
1013                        std::thread::sleep(Duration::from_micros(1));
1014                        lock0.commit().unwrap();
1015
1016                        let read3 = c_icow.read();
1017
1018                        assert_eq!(read2.item.s, 1);
1019                        assert_eq!(read3.item.s, 5);
1020                    }
1021                );
1022
1023            //rc.recv().unwrap();
1024
1025            for i in 0..1000000000
1026            {
1027                let read1 = icow.read();
1028
1029                if read1.item.s == 1
1030                {
1031                    continue;
1032                }
1033                else
1034                {
1035                    println!("{}", i);
1036                    break;
1037                }
1038            }
1039
1040            let read1 = icow.read();
1041            assert_eq!(read1.item.s, 5);
1042
1043            handler0.join().unwrap();
1044
1045            let mut lock0 = icow.try_clone().unwrap();
1046            lock0.s = 1;
1047            lock0.commit().unwrap();
1048        }
1049
1050        return;
1051    }
1052}