[docs]classRefcountMixin(MemoryMixin):""" This mixin adds a locked reference counter and methods to manipulate it, to facilitate copy-on-write optimizations. """
[docs]defacquire_unique(self):""" Call this function to return a version of this page which can be used for writing, which may or may not be the same object as before. If you use this you must immediately replace the shared reference you previously had with the new unique copy. """withself.lock:ifself.refcount==1:returnselfelse:self.refcount-=1returnself.copy({})# TODO: evaluate if it's worth making the lock a reentrant lock (RLock) so this can go in the else arm
[docs]defacquire_shared(self)->None:""" Call this function to indicate that this page has had a reference added to it and must be copied before it can be acquired uniquely again. Creating the object implicitly starts it with one shared reference. """withself.lock:self.refcount+=1
[docs]defrelease_shared(self)->None:""" Call this function to indicate that this page has had a shared reference to it released """withself.lock:self.refcount-=1