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