cluStaticData/once_const_static/core/
atomic_lock.rs

1
2use core::sync::atomic::AtomicU8;
3use core::sync::atomic::Ordering;
4use core::cell::UnsafeCell;
5
6use crate::once_const_static::generic::UnsafeGenericStaticData;
7use crate::once_const_static::generic::GenericStaticData;
8use crate::once_const_static::UnkStaticData;
9
10use crate::err::IgnoreInitErr;
11use crate::err::StaticErr;
12
13
14const UNINITIALIZED: u8 = 0;
15//неинициализированным
16
17const INITIALIZING: u8 = 1;
18//инициализация
19
20const INITIALIZED: u8 = 2;
21//инициализирован
22
23
24impl<T> UnkStaticData<T, AtomicU8> {
25	#[inline]
26	pub const fn new(a: T) -> Self {
27		Self {
28			data: UnsafeCell::new(a),
29			sync_data: AtomicU8::new(UNINITIALIZED),
30		}
31	}
32	
33	#[inline]
34	fn lock_logic<B: AtomicGenErr<VT, R>, A: FnOnce(VT) -> R, R, VT>(&self, v: VT, a: A) -> R {
35		match self.sync_data.compare_and_swap(UNINITIALIZED, INITIALIZING, Ordering::SeqCst) {
36			UNINITIALIZED => {
37				//неинициализированным
38				let result = a(v);
39				self.sync_data.store(INITIALIZED, Ordering::SeqCst);
40
41				result
42			},
43			INITIALIZING => {
44				//инициализация
45				while self.sync_data.load(Ordering::SeqCst) == INITIALIZING {}
46				B::create_err(v)
47			},
48			_ => {
49				B::create_err(v)
50			},
51			//инициализируется
52		}
53	}
54	
55	#[inline]
56	fn ignore_initialize_logic<B: AtomicGenErr<(), R>, A: FnOnce() -> R, R>(&self, a: A) -> R {
57		match self.sync_data.compare_and_swap(UNINITIALIZED, INITIALIZING, Ordering::SeqCst) {
58			UNINITIALIZED => {
59				//неинициализированным
60				let result = a();
61				self.sync_data.store(INITIALIZED, Ordering::SeqCst);
62				
63				result
64			},
65			INITIALIZING => {
66				//инициализация
67				while self.sync_data.load(Ordering::SeqCst) == INITIALIZING {}
68				B::create_err(())
69			},
70			_ => B::create_err(()),
71			//инициализируется
72		}
73	}
74	
75	#[inline]
76	fn is_init_state_logic(&self) -> bool {
77		match self.sync_data.load(Ordering::SeqCst) {
78			UNINITIALIZED => false,
79			//неинициализированным
80			
81			_ => true,
82		}
83	}
84	
85	#[inline]
86	fn raw_ignore_initialize_logic(&self) {
87		//self.sync_data.store(EARLY_GET, Ordering::SeqCst);
88		let _e = self.sync_data.compare_and_swap(UNINITIALIZED, INITIALIZING, Ordering::SeqCst);
89	}
90}
91
92
93impl<T> UnsafeGenericStaticData<T> for UnkStaticData<&'static T, AtomicU8> where T: 'static {
94	unsafe fn set_box(&self, v: Box<T>) -> Result<(), StaticErr<Box<T>>> {
95		self.lock_logic::<StaticErrPrev, _, _, _>(v, |v| {
96			#[allow(unused_unsafe)]
97			unsafe {
98				*self.data.get() = &*Box::into_raw(v);
99			}
100			Ok( () )
101		}/*, |v| Err(StaticErr::prev(v))*/)
102	}
103	
104	unsafe fn set_raw(&self, v: T) -> Result<(), StaticErr<T>> {
105		self.lock_logic::<StaticErrPrev, _, _, _>(v, |v| {
106			let v = Box::new(v);
107			
108			#[allow(unused_unsafe)]
109			unsafe {
110				*self.data.get() = &*Box::into_raw(v);
111			}
112			Ok( () )
113		}/*, |v| Err(StaticErr::prev(v))*/)
114	}
115}
116
117impl<T> GenericStaticData<T> for UnkStaticData<T, AtomicU8> {
118	fn set(&self, v: T) -> Result<(), StaticErr<T>> {
119		self.lock_logic::<StaticErrPrev, _, _, _>(v, 
120			|v| { unsafe { *self.data.get() = v; } Ok( () )},
121			//|v| Err(StaticErr::prev(v))
122		)
123	}
124	
125	fn replace(&self, v: T) -> Result<T, StaticErr<T>> {
126		self.lock_logic::<StaticErrPrev, _, _, _>(v, 
127			|v| Ok(	std::mem::replace(unsafe { &mut *self.data.get() }, v)	),
128			//|v| Err(	StaticErr::prev(v)							),
129			
130		)
131	}
132	
133	unsafe fn unsafe_replace(&self, v: T) -> T {
134		#[allow(unused_unsafe)]
135		std::mem::replace(unsafe { &mut *self.data.get() }, v)
136	}
137	
138	fn get<'a>(&'a self) -> &'a T {
139		unsafe{ &*self.data.get() }
140	}
141	
142	fn ignore_initialize(&self) -> Result<(), IgnoreInitErr> {
143		self.ignore_initialize_logic::<IgnoreInitErrPrev, _, _>( 
144			|| Ok( () ),
145			//|| Err( IgnoreInitErr::prev() )
146		)
147	}
148	
149	#[inline(always)]
150	fn ignore_initialize_dont_result(&self) {
151		self.raw_ignore_initialize_logic()
152	}
153	
154	#[inline(always)]
155	fn is_init_state(&self) -> bool {
156		self.is_init_state_logic()
157	}
158}
159
160
161trait AtomicGenErr<D, T> {
162	fn create_err(d: D) -> T;
163}
164
165
166enum IgnoreInitErrPrev {}
167impl<OKR, D> AtomicGenErr<D, Result<OKR, IgnoreInitErr>> for IgnoreInitErrPrev {
168	#[inline(always)]
169	fn create_err(_d: D) -> Result<OKR, IgnoreInitErr> {
170		Err(IgnoreInitErr::prev())
171	}
172}
173
174
175enum StaticErrPrev {}
176impl<OKR, D> AtomicGenErr<D, Result<OKR, StaticErr<D>>> for StaticErrPrev {
177	#[inline(always)]
178	fn create_err(d: D) -> Result<OKR, StaticErr<D>> {
179		Err(StaticErr::prev(d))
180	}
181}