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