#pragma once #include #include #include #include #include #include #include namespace c10::impl::cow { // A COWDeleterContext object is used as the `ctx` argument for DataPtr // to implement a Copy-on-write (COW) DataPtr. class C10_API COWDeleterContext { public: // Creates an instance, holding the pair of data and original // deleter. // // Note that the deleter will only be called in our destructor if // the last reference to this goes away without getting // materialized. explicit COWDeleterContext(std::unique_ptr data); // Increments the current refcount. void increment_refcount(); // See README.md in this directory to understand the locking // strategy. // Represents a reference to the context. // // This is returned by decrement_refcount to allow the caller to // copy the data under the shared lock. using NotLastReference = std::shared_lock; // Represents the last reference to the context. // // This will be returned by decrement_refcount when it is the last // reference remaining and after any pending copies have completed. using LastReference = std::unique_ptr; // Decrements the refcount, returning a handle indicating what to // do with it. std::variant decrement_refcount(); private: // The destructor is hidden, this should only ever be used within // UniqueVoidPtr using cow::delete_context as the deleter. ~COWDeleterContext(); std::shared_mutex mutex_; std::unique_ptr data_; std::atomic refcount_ = 1; }; // `cow_deleter` is used as the `ctx_deleter` for DataPtr to implement a COW // DataPtr. // // Warning: This should only be called on a pointer to a COWDeleterContext that // was allocated on the heap with `new`, because when the refcount reaches 0, // the context is deleted with `delete`. C10_API void cow_deleter(void* ctx); } // namespace c10::impl::cow