2

次のコードがあります(C++で記述):

StringRef クラスのコード:

    inline void retain() const {
        m_refCount.fetch_add(1, std::memory_order_relaxed);
    }
    inline void release() const {
        if(m_refCount.fetch_sub(1, std::memory_order_release) == 1){
            std::atomic_thread_fence(std::memory_order_acquire);
            deleteFromParent();
        }
    }

InternedString のコード:

public:
    inline InternedString(){
        m_ref = nullptr;
    }
    inline InternedString(const InternedString& other){
        m_ref = other.m_ref;
        if(m_ref)
            m_ref->retain();
    }
    inline InternedString(InternedString&& other){
        m_ref = other.m_ref;
        other.m_ref = nullptr;
    }
    inline InternedString& operator=(const InternedString& other){
        if(&other == this)
            return *this;
        if(other.m_ref)
            other.m_ref->retain();
        if(m_ref)
            m_ref->release();
        m_ref = other.m_ref;
        return *this;
    }
    inline InternedString& operator=(InternedString&& other){
        if(&other == this)
            return *this;
        if(m_ref)
            m_ref->release();
        m_ref = other.m_ref;
        other.m_ref = nullptr;
        return *this;
    }
    /*! @group Destructors */
    inline ~InternedString(){
        if(m_ref)
            m_ref->release();
    }
private:
    inline InternedString(const StringRef* ref){
        assert(ref);
        m_ref = ref;
        m_ref->retain();
    }

このコードを複数のスレッドで実行すると、同じオブジェクトに対して deleteFromParent() が複数回呼び出されます。理由がわかりません...リリースが終わったとしても、この動作はまだ発生しないはずです...

誰か助けてくれませんか?私は何を間違っていますか?

4

1 に答える 1