Skip to content

Socket::Address 求教 #716

@miniframework

Description

@miniframework

hi 能解释一下Address 里面的version ABA, version +1, version +2, version -1 的场景和为什么,设计原理?,这确实没看懂 尤其 if (nref > 1), if ((ver2 & 1)) if (ver1 == ver2 || ver1 + 1 == ver2) ) 能讲解一下每个if分支 的作用
Socket::Address

Socket::Address(SocketId id, SocketUniquePtr* ptr) {
    const base::ResourceId<Socket> slot = SlotOfSocketId(id);
    Socket* const m = address_resource(slot);
    if (__builtin_expect(m != NULL, 1)) {
        // acquire fence makes sure this thread sees latest changes before
        // Dereference() or Revive().
        const uint64_t vref1 = m->_versioned_ref.fetch_add(
            1, boost::memory_order_acquire);
        const uint32_t ver1 = VersionOfVRef(vref1);
        if (ver1 == VersionOfSocketId(id)) {
            ptr->reset(m);
            return 0;
        }
        const uint64_t vref2 = m->_versioned_ref.fetch_sub(
            1, boost::memory_order_release);
        const int32_t nref = NRefOfVRef(vref2);
        if (nref > 1) {
            return -1;
        } else if (__builtin_expect(nref == 1, 1)) {
            const uint32_t ver2 = VersionOfVRef(vref2);
            if ((ver2 & 1)) {
                if (ver1 == ver2 || ver1 + 1 == ver2) {
                    uint64_t expected_vref = vref2 - 1;
                    if (m->_versioned_ref.compare_exchange_strong(
                            expected_vref, MakeVRef(ver2 + 1, 0),
                            boost::memory_order_acquire,
                            boost::memory_order_relaxed)) {
                        m->OnRecycle();
                        return_resource(slot);
                    }
                } else {
                    CHECK(false) << "ref-version=" << ver1
                                 << " unref-version=" << ver2;
                }
            } else {
                CHECK_EQ(ver1, ver2);
                // Addressed a free slot.
            }
        } else {
            CHECK(false) << "Over dereferenced SocketId=" << id;
        }
    }
    return -1;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions