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