最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - Atomic implementation of intrusive shared pointers allowing construction from another being destroyed - Stack Overflow

programmeradmin2浏览0评论

Intrusive shared pointers have some advantages over classical control block shared pointers, as they allow, as far as I understand, atomic, lock-free concurrent operations with single writer and multiple readers, with one major exception : when a pointer is being reset and RefCount reaches zero, deleting the buffer, it cannot be concurrently copied, with a defined return value (either the old valid pointer with proper refcount, or a valid null pointer)

Is there any way to remove that restriction?

Here is a proposed, invalid implementation.

template<typename T>
class TIntrusiveSharedPointer
{
public:
    TIntrusiveSharedPointer() { AP.store(nullptr); }
    ~TIntrusiveSharedPointer() { Reset(); }
    
    // Resets the reference
    void Reset() noexcept
    {
        T* OldP = AP.exchange(nullptr, std::memory_order_acq_rel)
        if(OldP && OldP->RefCount.fetch_sub(1, std::memory_order_acq_rel)==1)
        {
            delete OldP;
        }
    }
    
    /* Copy constructor */ 
    TIntrusiveSharedPointer(const TIntrusiveSharedPointer& Other)
    {
        while(true)
        {
            T* NewP = Other.AP.load(std::memory_order_consume);
            if(!NewP)
            {
                AP.store(nullptr, std::memory_order_release);
                return;
            }
            //We cannot safely read RefCount here, because even if we loaded
            //A non zero NewP, RefCount might already have been decremented to 0
            //And pointer destroyed
            if(uint64 Count = NewP->RefCount.load(std::memory_order_acquire))
            {
                //Current RefCount is >=1, we can increment
                if(NewP->RefCountpare_exchange_weak (
                            Count, Count+1, std::memory_order_acquire))
                {
                    AP.store(NewP, std::memory_order_release);
                    return;
                }
            }
            else
            {
                //Current RefCount is zero, buffer about to be destroyed
                AP.store(nullptr, std::memory_order_release);
                return;
            }
        }
    }

private:
    std::atomic<T*> AP;
};

TIntrusiveSharedPointer<SomeClass> A;

void Thread1()
{
    A.Reset();
}

void Thread2()
{
    //Undefined behavior if run concurrently and A buffer is destroyed
    TIntrusiveSharedPointer<SomeClass> B(A);
}

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论