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] - 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    /// Attempts to perform the copy of the inner value for writing.
436    /// 
437    /// Non-blocking function i.e returns if it fails to acquire the
438    /// copy before some deadline.
439    /// 
440    /// # Returns
441    /// 
442    /// An [Option] is returned where the [Option::None] is returned if
443    /// it failed.
444    pub 
445    fn try_copy(&self) -> Option<ICoWCopy<'_, ITEM>>
446    {
447        let read = self.try_read()?;
448
449        let new_item = *read.item.as_ref();
450
451        let ret = 
452            ICoWCopy
453            { 
454                prev_item: read, 
455                new_item: new_item, 
456                inst: self 
457            };
458
459        return Some(ret);
460    }
461
462    /// Attempts to perform the copy of the inner value for 
463    /// **exclusive** writing.
464    /// 
465    /// Non-blocking function i.e returns if it fails to acquire the
466    /// copy before some deadline.
467    /// 
468    /// # Returns
469    /// 
470    /// An [Option] is returned where the [Option::None] is returned if
471    /// an exclusive CoW lock have already been issued.
472    pub 
473    fn try_copy_exclusivly(&self) -> Option<ICoWLock<'_, ITEM>>
474    {
475
476       let write_lock =  
477            match self.inner.try_write()
478            {
479                Ok(r) => r,
480                Err(TryLockError::Poisoned(e)) => e.into_inner(),
481                Err(TryLockError::WouldBlock) =>
482                    return None
483            };
484        
485        let new_item = *write_lock.as_ref(); 
486        
487        return Some(
488            ICoWLock{ prev_item: write_lock, item: new_item, inst: self }
489        );
490    }
491}
492
493impl<ITEM: fmt::Debug + Send + Clone> ICoW<ITEM>
494{
495    /// Attempts to perform the clone of the inner value for writing.
496    /// 
497    /// Non-blocking function i.e returns if it fails to acquire the
498    /// clone before some deadline.
499    /// 
500    /// # Returns
501    /// 
502    /// An [Option] is returned where the [Option::None] is returned if
503    /// it failed.
504    pub 
505    fn try_clone(&self) -> Option<ICoWCopy<'_, ITEM>>
506    {
507        let read = self.try_read()?;
508
509        let new_item = read.item.as_ref().clone();
510
511        let ret = 
512            ICoWCopy
513            { 
514                prev_item: read, 
515                new_item: new_item, 
516                inst: self 
517            };
518
519        return Some(ret);
520    }
521
522    /// Attempts to perform the clone of the inner value for 
523    /// **exclusive** writing.
524    /// 
525    /// Non-blocking function i.e returns if it fails to acquire the
526    /// clone before some deadline.
527    /// 
528    /// # Returns
529    /// 
530    /// An [Option] is returned where the [Option::None] is returned if
531    /// an exclusive CoW lock have already been issued.
532    pub 
533    fn try_clone_exclusivly(&self) -> Option<ICoWLock<'_, ITEM>>
534    {
535        
536        let write_lock =  
537            match self.inner.try_write()
538            {
539                Ok(r) => r,
540                Err(TryLockError::Poisoned(e)) => e.into_inner(),
541                Err(TryLockError::WouldBlock) =>
542                    return None
543            };
544        
545        let new_item = write_lock.as_ref().clone();
546        
547        return Some(
548            ICoWLock{ prev_item: write_lock, item: new_item, inst: self }
549        );
550    }
551}
552
553impl<ITEM: fmt::Debug + Send + Default> ICoW<ITEM>
554{
555    /// Attempts to init default of the inner value for writing.
556    /// 
557    /// Non-blocking function i.e returns if it fails to acquire the
558    /// clone before some deadline.
559    /// 
560    /// # Returns
561    /// 
562    /// An [Option] is returned where the [Option::None] is returned if
563    /// it failed.
564    pub 
565    fn try_default(&self) -> Option<ICoWCopy<'_, ITEM>>
566    {
567        let read = self.try_read()?;
568
569        let new_item = ITEM::default();
570
571        let ret = 
572            ICoWCopy
573            { 
574                prev_item: read, 
575                new_item: new_item, 
576                inst: self 
577            };
578
579        return Some(ret);
580    }
581      
582
583    /// Attempts to init default of the inner value for 
584    /// **exclusive** writing.
585    /// 
586    /// Non-blocking function i.e returns if it fails to acquire the
587    /// clone before some deadline.
588    /// 
589    /// # Returns
590    /// 
591    /// An [Option] is returned where the [Option::None] is returned if
592    /// an exclusive CoW lock have already been issued.
593    pub 
594    fn try_default_exclusivly(&self) -> Option<ICoWLock<'_, ITEM>>
595    {
596        let write_lock =  
597            match self.inner.try_write()
598            {
599                Ok(r) => r,
600                Err(TryLockError::Poisoned(e)) => e.into_inner(),
601                Err(TryLockError::WouldBlock) =>
602                    return None
603            };
604        
605        let new_item = ITEM::default();
606        
607        return Some(
608            ICoWLock{ prev_item: write_lock, item: new_item, inst: self }
609        );
610    }
611}
612
613
614#[cfg(test)]
615mod test
616{
617    use std::{sync::{mpsc, LazyLock}, time::{Duration, Instant}};
618
619    use super::*;
620
621
622
623
624    #[test]
625    fn test_3()
626    {
627        #[derive(Debug, Clone)]
628        struct Test { s: String };
629
630        let icow = ICoW::new(Test{ s: "test".into() });
631
632        for _ in 0..10
633        {
634            let s = Instant::now();
635
636            let read0 = icow.read();
637
638            let e = s.elapsed();
639
640            println!("{:?}", e);
641        }
642
643    }
644
645    #[test]
646    fn test_33()
647    {
648        #[derive(Debug, Clone)]
649        struct Test { s: String };
650
651        let icow = ICoW::new(Test{ s: "test".into() });
652
653        let write_ex = icow.try_clone_exclusivly().unwrap();
654
655        {
656        let write_ex_err = icow.try_clone_exclusivly();
657        assert_eq!(write_ex_err.is_none(), true);
658        }
659
660        let write_ex_err = icow.try_clone();
661        assert_eq!(write_ex_err.is_none(), true);
662
663        let read1 = icow.try_read();
664        assert_eq!(read1.is_none(), true);
665
666        drop(write_ex);
667
668        drop(icow);
669
670    }
671
672    #[test]
673    fn test_4()
674    {
675        #[derive(Debug, Clone)]
676        struct Test { s: u32 }
677
678        let icow = ICoW::new(Test{ s: 1 });
679
680        let read0 = icow.read();
681        let read1 = icow.read();
682
683        let mut excl_write = icow.try_clone_exclusivly().unwrap();
684
685        excl_write.item.s = 5;
686
687
688        excl_write.commit().unwrap();
689
690        assert_eq!(read0.item.s, 1);
691
692        let read3 = icow.read();
693        assert_eq!(read3.item.s, 5);
694
695        let mut writing = icow.try_clone().unwrap();
696        writing.s = 4;
697
698        writing.commit().unwrap();
699
700        assert_eq!(read0.item.s, 1);
701        assert_eq!(read3.item.s, 5);
702
703        let read4 = icow.read();
704        assert_eq!(read4.s, 4);
705    }
706
707    #[test]
708    fn test_5()
709    {
710        #[derive(Debug, Clone)]
711        struct Test { s: u32 }
712
713        let icow = Arc::new(ICoW::new(Test{ s: 1 }));
714
715        let read0 = icow.read();
716        let read2 = icow.read();
717        
718        let c_icow = icow.clone();
719
720        let (se, rc) = mpsc::channel::<()>();
721        let handler0 = 
722            std::thread::spawn(move || 
723                {
724                    let mut lock0 = c_icow.try_clone_exclusivly().unwrap();
725
726                    se.send(()).unwrap();
727
728                    lock0.item.s = 5;
729
730                    std::thread::sleep(Duration::from_micros(2));
731
732                    lock0.commit().unwrap();
733                }
734            );
735
736        rc.recv().unwrap();
737
738        let s = Instant::now();
739
740        let read1 = icow.read();
741        
742        let e = s.elapsed();
743
744        println!("{:?}", e);
745
746        
747        assert_eq!(read1.item.s, 5);
748        assert_eq!(read0.item.s, 1);
749
750        handler0.join().unwrap();
751
752        let weak0 = read0.weak();
753        let weak1 = read1.weak();
754
755        drop(read0);
756        drop(read1);
757
758        assert_eq!(weak0.upgrade().is_some(), true);
759        assert_eq!(weak1.upgrade().is_some(), true);
760
761        drop(read2);
762        assert_eq!(weak0.upgrade().is_none(), true);
763        assert_eq!(weak1.upgrade().is_some(), true);
764    }
765
766
767    #[test]
768    fn test_6()
769    {
770        #[derive(Debug, Clone)]
771        struct Test { s: u32 }
772
773        let icow = Arc::new(ICoW::new(Test{ s: 1 }));
774
775        let read0 = icow.read();
776        let read2 = icow.read();
777        
778        let c_icow = icow.clone();
779
780        let (se, rc) = mpsc::channel::<()>();
781        let handler0 = 
782            std::thread::spawn(move || 
783                {
784                    let read2 = c_icow.read();
785
786                    let mut lock0 = c_icow.try_clone_exclusivly().unwrap();
787
788                    se.send(()).unwrap();
789
790                    lock0.item.s = 5;
791
792                    std::thread::sleep(Duration::from_nanos(50));
793                    lock0.commit().unwrap();
794
795                    let read3 = c_icow.read();
796
797                    assert_eq!(read2.item.s, 1);
798                    assert_eq!(read3.item.s, 5);
799                }
800            );
801
802        rc.recv().unwrap();
803
804        for _ in 0..100000000
805        {
806            let read1 = icow.read();
807
808            if read1.item.s == 1
809            {
810                continue;
811            }
812            else
813            {
814                break;
815            }
816        }
817
818        let read1 = icow.read();
819        assert_eq!(read1.item.s, 5);
820
821        handler0.join().unwrap();
822
823        return;
824    }
825
826
827    #[test]
828    fn test_7()
829    {
830        #[derive(Debug, Clone)]
831        struct TestStruct { s: u32 }
832
833        impl TestStruct
834        {
835            fn new(s: u32) -> Self
836            {
837                return Self{ s: s };
838            }
839        }
840
841        static VAL: LazyLock<ICoW<TestStruct>> = 
842            LazyLock::new(|| ICoW::new(TestStruct::new(1))); 
843        
844
845        
846        
847            let borrow1 = VAL.read();
848            assert_eq!(borrow1.item.s, 1);
849
850            let (mpsc_send, mpsc_rcv) = mpsc::channel::<u64>();
851            let (mpsc_send2, mpsc_rcv2) = mpsc::channel::<u64>();
852
853            let thread1 = 
854                std::thread::spawn(move ||
855                    {
856                        for _ in 0..1000
857                        {
858                            let _ = mpsc_rcv2.recv();
859                            let borrow1 = VAL.read();
860
861                            let mut transaction = VAL.try_clone_exclusivly().unwrap();
862
863                            transaction.item.s = 5;
864
865                            
866
867                            std::thread::sleep(Duration::from_nanos(1001));
868                            transaction.commit().unwrap();
869
870                            let borrow2 = VAL.read();
871                            
872
873                            assert_eq!(borrow1.item.s, 1);
874
875                            assert_eq!(borrow2.item.s, 5);
876
877                            let _ = mpsc_send.send(1);
878                        }
879                    }
880                );
881            
882            
883
884            for x in 0..1000
885            {
886                println!("{}", x);
887                mpsc_send2.send(1).unwrap();
888                let _ = mpsc_rcv.recv();
889
890                let borrow1 = VAL.read();
891                assert_eq!(borrow1.item.s, 5);
892
893                let mut transaction = VAL.try_clone_exclusivly().unwrap();
894                transaction.item.s = 1;
895                transaction.commit().unwrap();
896
897                let borrow1 = VAL.read();
898                assert_eq!(borrow1.item.s, 1);
899                
900            }
901            
902            
903
904            thread1.join().unwrap();
905
906            
907    }
908
909
910    #[test]
911    fn test_8()
912    {
913        #[derive(Debug, Clone)]
914        struct Test { s: u32 }
915
916        let icow = Arc::new(ICoW::new(Test{ s: 1 }));
917
918        for _ in 0..20
919        {
920            let read0 = icow.read();
921            let read2 = icow.read();
922            
923            let c_icow = icow.clone();
924
925            //let (se, rc) = mpsc::channel::<()>();
926            let handler0 = 
927                std::thread::spawn(move || 
928                    {
929                        let read2 = c_icow.read();
930
931                        let mut lock0 = c_icow.try_clone().unwrap();
932
933                        //se.send(()).unwrap();
934
935                        lock0.s = 5;
936
937                        std::thread::sleep(Duration::from_micros(1));
938                        lock0.commit().unwrap();
939
940                        let read3 = c_icow.read();
941
942                        assert_eq!(read2.item.s, 1);
943                        assert_eq!(read3.item.s, 5);
944                    }
945                );
946
947            //rc.recv().unwrap();
948
949            for i in 0..1000000000
950            {
951                let read1 = icow.read();
952
953                if read1.item.s == 1
954                {
955                    continue;
956                }
957                else
958                {
959                    println!("{}", i);
960                    break;
961                }
962            }
963
964            let read1 = icow.read();
965            assert_eq!(read1.item.s, 5);
966
967            handler0.join().unwrap();
968
969            let mut lock0 = icow.try_clone().unwrap();
970            lock0.s = 1;
971            lock0.commit().unwrap();
972        }
973
974        return;
975    }
976}