diff options
| author | xtraeme <xtraeme@NetBSD.org> | 2008-05-06 22:57:26 +0000 |
|---|---|---|
| committer | xtraeme <xtraeme@NetBSD.org> | 2008-05-06 22:57:26 +0000 |
| commit | 35fe7cdcf170c86a63bf7a3c54a5fb98a14cd457 (patch) | |
| tree | 41eecf8a0520bdf194e071463b44239b9309e074 /common/lib/libprop/prop_array.c | |
| parent | 5e2fa55b72208086b2defc94f6c6b203dad905fc (diff) | |
prop_object_iterator_next() and prop_object_iterator_reset() were
acquiring the rwlock recursively in some paths.
Introduce _prop_rwlock_tryrdlock() and use it in these functions, so
that the rwlock is *always* acquired once, while here add some
_PROP_RWLOCK_OWNED asserts to verify.
This definitely fixes the "locking against myself" panics.
Diffstat (limited to 'common/lib/libprop/prop_array.c')
| -rw-r--r-- | common/lib/libprop/prop_array.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/common/lib/libprop/prop_array.c b/common/lib/libprop/prop_array.c index 58e9ae4cdba..9ae85e15fed 100644 --- a/common/lib/libprop/prop_array.c +++ b/common/lib/libprop/prop_array.c @@ -1,4 +1,4 @@ -/* $NetBSD: prop_array.c,v 1.13 2008/05/06 13:52:51 xtraeme Exp $ */ +/* $NetBSD: prop_array.c,v 1.14 2008/05/06 22:57:26 xtraeme Exp $ */ /*- * Copyright (c) 2006, 2007 The NetBSD Foundation, Inc. @@ -312,10 +312,11 @@ _prop_array_iterator_next_object(void *v) struct _prop_array_iterator *pai = v; prop_array_t pa = pai->pai_base.pi_obj; prop_object_t po = NULL; + bool acquired; _PROP_ASSERT(prop_object_is_array(pa)); - - _PROP_RWLOCK_RDLOCK(pa->pa_rwlock); + acquired = _prop_rwlock_tryrdlock(&pa->pa_rwlock); + _PROP_RWLOCK_OWNED(pa->pa_rwlock); if (pa->pa_version != pai->pai_base.pi_version) goto out; /* array changed during iteration */ @@ -329,7 +330,9 @@ _prop_array_iterator_next_object(void *v) pai->pai_index++; out: - _PROP_RWLOCK_UNLOCK(pa->pa_rwlock); + if (acquired) { + _PROP_RWLOCK_UNLOCK(pa->pa_rwlock); + } return (po); } @@ -338,12 +341,18 @@ _prop_array_iterator_reset(void *v) { struct _prop_array_iterator *pai = v; prop_array_t pa = pai->pai_base.pi_obj; + bool acquired; _PROP_ASSERT(prop_object_is_array(pa)); + acquired = _prop_rwlock_tryrdlock(&pa->pa_rwlock); _PROP_RWLOCK_OWNED(pa->pa_rwlock); pai->pai_index = 0; pai->pai_base.pi_version = pa->pa_version; + + if (acquired) { + _PROP_RWLOCK_UNLOCK(pa->pa_rwlock); + } } /* |
