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