Is it safe to read a weak pointer while freeing it?

Is it safe to read a non-atomic weak pointer from another thread than the object is being freed from?

In general, I know that properties should be made by atoms whenever there can be concurrent accesses, at least one of which is a write operation. But I have to wonder if the ARC write operation (setting the pointer to zero) is somehow special. If not, I expected to see more warnings about this possible issue. Perhaps weak pointers are implicitly atomic?

+3


source to share


1 answer


It's safe. Zeroing weak pointer and weak pointer access is between spinlock_lock and spinlock_unlock.

Take a look at the runtime source code http://opensource.apple.com/source/objc4/objc4-646/runtime/NSObject.mm

Accessing Weak Pointers

id
objc_loadWeakRetained(id *location)
{
    id result;

    SideTable *table;
    spinlock_t *lock;

 retry:
    result = *location;
    if (!result) return nil;

    table = SideTable::tableForPointer(result);
    lock = &table->slock;

    spinlock_lock(lock);
    if (*location != result) {
        spinlock_unlock(lock);
        goto retry;
    }

    result = weak_read_no_lock(&table->weak_table, location);

    spinlock_unlock(lock);
    return result;
}

      



Zeroing Weak Pointers

void 
objc_object::sidetable_clearDeallocating()
{
    SideTable *table = SideTable::tableForPointer(this);

    // clear any weak table items
    // clear extra retain count and deallocating bit
    // (fixme warn or abort if extra retain count == 0 ?)
    spinlock_lock(&table->slock);
    RefcountMap::iterator it = table->refcnts.find(this);
    if (it != table->refcnts.end()) {
        if (it->second & SIDE_TABLE_WEAKLY_REFERENCED) {
            weak_clear_no_lock(&table->weak_table, (id)this);
        }
        table->refcnts.erase(it);
    }
    spinlock_unlock(&table->slock);
}

      

And the stream of object release is fooobar.com/questions/2231965 / ...

+3


source







All Articles