Core: new blenlib library for implicit-sharing #105994
|
@ -49,21 +49,28 @@ class ImplicitSharingInfo : blender::NonCopyable, blender::NonMovable {
|
||||||
BLI_assert(this->is_mutable());
|
BLI_assert(this->is_mutable());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** True if there are other const references to the resource, meaning it cannot be modified. */
|
||||||
bool is_shared() const
|
bool is_shared() const
|
||||||
{
|
{
|
||||||
return users_.load(std::memory_order_relaxed) >= 2;
|
return users_.load(std::memory_order_relaxed) >= 2;
|
||||||
JacquesLucke marked this conversation as resolved
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
/** Whether the resource can be modified without a copy because there is only one owner. */
|
||||||
bool is_mutable() const
|
bool is_mutable() const
|
||||||
{
|
{
|
||||||
return !this->is_shared();
|
return !this->is_shared();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Call when a the data has a new additional owner. */
|
||||||
void add_user() const
|
void add_user() const
|
||||||
{
|
{
|
||||||
users_.fetch_add(1, std::memory_order_relaxed);
|
users_.fetch_add(1, std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call when the data is no longer needed. This might just decrement the user count, or it might
|
||||||
|
* also delete the data if this was the last user.
|
||||||
|
*/
|
||||||
void remove_user_and_delete_if_last() const
|
void remove_user_and_delete_if_last() const
|
||||||
{
|
{
|
||||||
const int old_user_count = users_.fetch_sub(1, std::memory_order_relaxed);
|
const int old_user_count = users_.fetch_sub(1, std::memory_order_relaxed);
|
||||||
brecht marked this conversation as resolved
Outdated
Brecht Van Lommel
commented
My understanding is that user count decrement requires For example libc++ does this for shared_ptr. More details: My understanding is that user count decrement requires `std::memory_order_acq_rel`, while increment can use `std::memory_order_relaxed`.
For example libc++ does this for shared_ptr. More details:
https://stackoverflow.com/questions/48124031/stdmemory-order-relaxed-atomicity-with-respect-to-the-same-atomic-variable
|
|||||||
|
@ -80,8 +87,8 @@ class ImplicitSharingInfo : blender::NonCopyable, blender::NonMovable {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes it easy to embed implicit-sharing behavior into a struct. This also allows the subclass to
|
* Makes it easy to embed implicit-sharing behavior into a struct. Structs that derive from this
|
||||||
* be used with #ImplicitSharingPtr.
|
* class can be used with #ImplicitSharingPtr.
|
||||||
*/
|
*/
|
||||||
class ImplicitSharingMixin : public ImplicitSharingInfo {
|
class ImplicitSharingMixin : public ImplicitSharingInfo {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace blender {
|
||||||
/**
|
/**
|
||||||
* #ImplicitSharingPtr is a smart pointer that manages implicit sharing. It's designed to work with
|
* #ImplicitSharingPtr is a smart pointer that manages implicit sharing. It's designed to work with
|
||||||
* types that derive from #ImplicitSharingMixin. It is fairly similar to #std::shared_ptr but
|
* types that derive from #ImplicitSharingMixin. It is fairly similar to #std::shared_ptr but
|
||||||
* expects the reference count to be embedded in the data.
|
* requires the reference count to be embedded in the data.
|
||||||
JacquesLucke marked this conversation as resolved
Outdated
Hans Goudey
commented
`expects` -> `requires`, right? `std::make_shared` will allocate the use count with the object so it's helpful to clarify this a bit.
|
|||||||
*/
|
*/
|
||||||
template<typename T> class ImplicitSharingPtr {
|
template<typename T> class ImplicitSharingPtr {
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in New Issue
This could be over-documenting and redundant, I wonder what you think, but possibly some comments like this could help people answer their questions faster:
/** True if there are other const references to the resource, meaning it cannot be modified. */
/** Whether the resource can be modified without a copy. */
/** Call when creating another const reference/pointer to the data. */
etc.