Neil Perrin wrote:
> Matthew Ahrens wrote:
>> Neil Perrin wrote:
>>>
>>> Ricardo M. Correia wrote:
>>>> Ricardo M. Correia wrote:
>>>>> boolean_t need_lock = !RW_LOCK_HELD(&dp->dp_config_rwlock);
>>>>>
>>>>> if (need_lock)
>>>>>         rw_enter(&dp->dp_config_rwlock, RW_READER);
>>>>>
>>>> Maybe I posted to soon.
>>>> Am I right that this specific code (in dsl_dataset.c) would work 
>>>> correctly if RW_LOCK_HELD() returned true if *another* thread is 
>>>> holding the lock as a reader?
>>>
>>> Yes this looks like a bug to me as well.
>>
>> This is not a bug, it is the designed behavior.  To tell if this 
>> specific thread is holding the lock for reader would require a 
>> performance hit (eg, see rrwlock.c behavior when rr_writer_wanted is 
>> set).
>>
>> --matt
> 
> - I'm confused then. The dp_config_rwlock lock must be held as it's
> asserted in dsl_prop_get_ds_locked() However, the lock can be
> dropped immediately after the test dsl_dataset_open_obj() as it only
> checks if anyone is holding it - not just the caller. Am I missing 
> something?

So, we use RW_LOCK_HELD() to mean, "might this thread hold the lock?"  and it 
is generally only used in assertions.  Eg, some routine should only be called 
with the lock held, so we "ASSERT(RW_LOCK_HELD(lock))".  The fact that 
sometimes the implementation of RW_LOCK_HELD() returns TRUE when this thread 
does not in fact hold the lock is fine.

In this case, we are using it a bit differently.  The current thread must 
*not* hold the lock for reader.  We use RW_LOCK_HELD() to determine 
definitively if this thread holds the lock for writer or not.  The behavior we 
want is:  if this thread already holds the lock for writer, we don't need to 
re-grab it.  Otherwise, we grab the lock for READER.

However, now that I go look at the implementation of RW_LOCK_HELD(), it 
doesn't do what this code expects; it should be using RW_WRITE_HELD().

--matt

Reply via email to