1#![feature(assert_matches)]
2
3#[cfg(test)]
22mod tests;
23
24#[cfg(feature = "global")]
25mod global;
26
27use std::{
28 cell::{Cell, RefCell},
29 mem,
30};
31
32#[repr(transparent)]
33#[derive(Clone, Copy)]
34struct Generation(NonNull<Cell<u32>>);
35
36impl Generation
37{
38 fn new() -> Self { FreeList::unfree().unwrap_or_else(FreshList::fresh) }
39
40 fn get(&self) -> u32 { unsafe { self.0.as_ref() }.get() }
41
42 fn free(this: Self)
43 {
44 let c = unsafe { this.0.as_ref() };
45
46 if c.get() == u32::MAX {
47 c.set(0);
48 } else {
49 c.set(c.get() + 1);
50 FreeList::free(this);
51 }
52 }
53}
54
55thread_local! {
56 static FREELIST : RefCell<FreeList> = RefCell::new(FreeList::new());
57 static FRESHLIST : RefCell<FreshList> = RefCell::new(FreshList::new());
58 static LOCK : Lock = Lock::new();
59 static DROPQUEUE : RefCell<DropQueue> = RefCell::new(DropQueue::new());
60}
61
62struct Lock(Cell<isize>);
63
64#[derive(Debug)]
69pub struct Reading(());
70pub fn reading() -> Option<Reading> { Lock::reading() }
71
72#[derive(Debug)]
77pub struct Writing(());
78pub fn writing() -> Option<Writing> { Lock::writing() }
79
80impl Lock
81{
82 fn new() -> Self { Self(Cell::new(0)) }
83 fn reading() -> Option<Reading>
84 {
85 if Self::readable() {
86 unsafe { Self::read() }
87 Some(Reading(()))
88 } else {
89 None
90 }
91 }
92
93 fn writing() -> Option<Writing>
94 {
95 if Self::writable() {
96 unsafe { Self::write() }
97 Some(Writing(()))
98 } else {
99 None
100 }
101 }
102
103 fn writable() -> bool { LOCK.with(|l| l.0.get() == 0) }
104 unsafe fn write() { LOCK.with(|l| l.0.set(-1)) }
105 unsafe fn unwrite() { LOCK.with(|l| l.0.set(0)) }
106
107 fn readable() -> bool { LOCK.with(|l| l.0.get() >= 0) }
108 unsafe fn read() { LOCK.with(|l| l.0.set(l.0.get() + 1)) }
109 unsafe fn unread() { LOCK.with(|l| l.0.set(l.0.get() - 1)) }
110}
111
112impl Drop for Reading
113{
114 fn drop(&mut self)
115 {
116 unsafe { Lock::unread() }
117 if let Some(mut wl) = Lock::writing() {
118 let d = DropQueue::clear(&mut wl);
119 mem::drop(wl);
120 mem::drop(d);
121 }
122 }
123}
124
125impl Clone for Reading
126{
127 fn clone(&self) -> Self
128 {
129 unsafe { Lock::read() }
130 Self(())
131 }
132}
133
134impl Drop for Writing
135{
136 fn drop(&mut self)
137 {
138 let q = DropQueue::clear(self);
139 unsafe { Lock::unwrite() }
140 mem::drop(q);
141 }
142}
143
144struct FreeList(Vec<Generation>);
145struct FreshList(usize, Vec<Cell<u32>>, Vec<Vec<Cell<u32>>>);
146
147impl FreeList
148{
149 fn new() -> Self { Self(Vec::with_capacity(32)) }
150
151 fn free_(&mut self, gen: Generation) { self.0.push(gen) }
152 fn free(gen: Generation) { FREELIST.with(|fl| fl.borrow_mut().free_(gen)) }
153
154 fn unfree_(&mut self) -> Option<Generation> { self.0.pop() }
155 fn unfree() -> Option<Generation> { FREELIST.with(|fl| fl.borrow_mut().unfree_()) }
156}
157
158impl FreshList
159{
160 const INIT: u32 = 1;
161 fn new() -> Self { Self(0, Self::more(32), vec![]) }
162
163 fn fresh_(&mut self) -> Generation
164 {
165 if self.0 == self.1.len() {
166 self.refresh()
167 }
168 self.0 += 1;
169 Generation(NonNull::from(&self.1[self.0 - 1]))
170 }
171
172 fn fresh() -> Generation { FRESHLIST.with(|fl| fl.borrow_mut().fresh_()) }
173
174 fn refresh(&mut self)
175 {
176 self.2
177 .push(mem::replace(&mut self.1, Self::more(self.0 + self.0 / 2)));
178 self.0 = 0;
179 }
180
181 fn more(n: usize) -> Vec<Cell<u32>> { vec![Cell::new(Self::INIT); n] }
182}
183
184trait DropLater {}
185impl<T> DropLater for T {}
186struct DropQueue(Vec<Box<dyn DropLater>>);
187
188impl DropQueue
189{
190 fn new() -> Self { Self(Vec::with_capacity(32)) }
191
192 fn clear_(&mut self, _wl: &mut Writing) -> impl Drop
193 {
194 let re = Vec::with_capacity(self.0.len());
195 mem::replace(&mut self.0, re)
196 }
197
198 fn clear(wl: &mut Writing) -> impl Drop { DROPQUEUE.with(|dq| dq.borrow_mut().clear_(wl)) }
199
200 fn defer_(&mut self, val: Box<dyn DropLater>) { self.0.push(val) }
201 fn defer(val: Box<dyn DropLater>) { DROPQUEUE.with(|dq| dq.borrow_mut().defer_(val)) }
202}
203
204use std::{mem::ManuallyDrop, ptr::NonNull};
205
206pub struct Strong<T: 'static>
213{
214 gen: Generation,
215 ptr: ManuallyDrop<Box<T>>,
216}
217
218pub struct Weak<T: 'static>
223{
224 genref: u32,
225 gen: Generation,
226 ptr: NonNull<T>,
227}
228
229impl<T: 'static> Drop for Strong<T>
230{
231 fn drop(&mut self)
232 {
233 Generation::free(self.gen);
234 if let Some(wl) = Lock::writing() {
235 let d = unsafe { ManuallyDrop::take(&mut self.ptr) };
236 mem::drop(wl);
237 mem::drop(d);
238 } else {
239 DropQueue::defer(unsafe { ManuallyDrop::take(&mut self.ptr) } as Box<dyn DropLater>);
240 }
241 }
242}
243
244impl<T: 'static> Strong<T>
245{
246 pub fn new(t: T) -> Self { Self::from(Box::new(t)) }
247
248 pub fn alias(&self) -> Weak<T>
249 {
250 Weak {
251 genref: self.gen.get(),
252 gen: self.gen,
253 ptr: NonNull::from((*self.ptr).as_ref()),
254 }
255 }
256
257 pub fn take(mut self, _wl: &mut Writing) -> Box<T>
258 {
259 Generation::free(self.gen);
260 let b = unsafe { ManuallyDrop::take(&mut self.ptr) };
261 mem::forget(self);
262 b
263 }
264
265 pub fn as_ref(&self, _rl: &Reading) -> &T { &self.ptr }
266 pub fn as_mut(&mut self, _wl: &mut Writing) -> &mut T { &mut self.ptr }
267
268 pub fn map<F, U>(&self, rl: &Reading, f: F) -> Weak<U>
269 where
270 for<'a> F: Fn(&'a T) -> &'a U,
271 {
272 Weak {
273 genref: self.gen.get(),
274 gen: self.gen,
275 ptr: NonNull::from(f(self.as_ref(rl))),
276 }
277 }
278}
279
280impl<T: 'static> From<Box<T>> for Strong<T>
281{
282 fn from(b: Box<T>) -> Self
283 {
284 Self {
285 gen: Generation::new(),
286 ptr: ManuallyDrop::new(b),
287 }
288 }
289}
290
291impl<T: 'static> Weak<T>
292{
293 pub fn dangling() -> Self
294 {
295 static mut ZERO: Cell<u32> = Cell::new(0);
296 Weak {
297 genref: u32::MAX,
298 gen: Generation(NonNull::from(unsafe { &mut ZERO })),
299 ptr: NonNull::dangling(),
300 }
301 }
302
303 pub fn is_valid(&self) -> bool { self.genref == self.gen.get() }
304
305 pub fn try_ref(&self, _rl: &Reading) -> Option<&T>
306 {
307 if self.is_valid() {
308 Some(unsafe { self.ptr.as_ref() })
309 } else {
310 None
311 }
312 }
313
314 pub fn try_mut(&mut self, _wl: &mut Writing) -> Option<&mut T>
315 {
316 if self.is_valid() {
317 Some(unsafe { self.ptr.as_mut() })
318 } else {
319 None
320 }
321 }
322
323 pub fn try_map<F, U>(&self, rl: &Reading, f: F) -> Option<Weak<U>>
324 where
325 for<'a> F: Fn(&'a T) -> &'a U,
326 {
327 if let Some(a) = self.try_ref(rl) {
328 Some(Weak {
329 genref: self.genref,
330 gen: self.gen,
331 ptr: NonNull::from(f(a)),
332 })
333 } else {
334 None
335 }
336 }
337}
338
339impl<T: 'static> Clone for Weak<T>
340{
341 fn clone(&self) -> Self { *self }
342}
343
344impl<T: 'static> Copy for Weak<T> {}
345
346pub enum Ref<T: 'static>
347{
348 Strong(Strong<T>),
349 Weak(Weak<T>),
350}
351
352impl<T: 'static> Ref<T>
353{
354 pub fn new(t: T) -> Self { Self::Strong(Strong::new(t)) }
356
357 pub fn try_as_ref(&self, rl: &Reading) -> Option<&T>
358 {
359 match self {
360 Ref::Strong(s) => Some(s.as_ref(rl)),
361 Ref::Weak(w) => w.try_ref(rl),
362 }
363 }
364
365 pub fn try_mut(&mut self, wl: &mut Writing) -> Option<&mut T>
366 {
367 match self {
368 Ref::Strong(s) => Some(s.as_mut(wl)),
369 Ref::Weak(w) => w.try_mut(wl),
370 }
371 }
372
373 pub fn try_map<F, U>(&self, rl: &Reading, f: F) -> Option<Ref<U>>
374 where
375 for<'a> F: Fn(&'a T) -> &'a U,
376 {
377 match self {
378 Ref::Strong(s) => Some(Ref::Weak(s.map(rl, f))),
379 Ref::Weak(w) => w.try_map(rl, f).map(Ref::Weak),
380 }
381 }
382
383 pub fn is_weak(&self) -> bool
384 {
385 match self {
386 Ref::Strong(_) => false,
387 Ref::Weak(_) => true,
388 }
389 }
390
391 pub fn is_strong(&self) -> bool
392 {
393 match self {
394 Ref::Strong(_) => false,
395 Ref::Weak(_) => true,
396 }
397 }
398
399 pub fn is_valid(&self) -> bool
400 {
401 match self {
402 Ref::Strong(_) => true,
403 Ref::Weak(w) => w.is_valid(),
404 }
405 }
406}
407
408impl<T: 'static> Clone for Ref<T>
409{
410 fn clone(&self) -> Self
411 {
412 match self {
413 Self::Strong(s) => Self::Weak(s.alias()),
414 Self::Weak(w) => Self::Weak(*w),
415 }
416 }
417}
418
419impl<T: 'static> From<Weak<T>> for Ref<T>
420{
421 fn from(w: Weak<T>) -> Self { Ref::Weak(w) }
422}
423
424impl<T: 'static> From<Strong<T>> for Ref<T>
425{
426 fn from(s: Strong<T>) -> Self { Ref::Strong(s) }
427}