Refactor witness_unlock() to fix undefined test behavior.
This resolves #396.
This commit is contained in:
parent
1d57c03e33
commit
4752a54eeb
@ -607,6 +607,7 @@ witness_lock
|
|||||||
witness_lock_error
|
witness_lock_error
|
||||||
witness_lockless_error
|
witness_lockless_error
|
||||||
witness_not_owner_error
|
witness_not_owner_error
|
||||||
|
witness_owner
|
||||||
witness_owner_error
|
witness_owner_error
|
||||||
witness_postfork_child
|
witness_postfork_child
|
||||||
witness_postfork_parent
|
witness_postfork_parent
|
||||||
|
@ -108,6 +108,7 @@ void witness_postfork_child(tsd_t *tsd);
|
|||||||
#ifdef JEMALLOC_H_INLINES
|
#ifdef JEMALLOC_H_INLINES
|
||||||
|
|
||||||
#ifndef JEMALLOC_ENABLE_INLINE
|
#ifndef JEMALLOC_ENABLE_INLINE
|
||||||
|
bool witness_owner(tsd_t *tsd, const witness_t *witness);
|
||||||
void witness_assert_owner(tsdn_t *tsdn, const witness_t *witness);
|
void witness_assert_owner(tsdn_t *tsdn, const witness_t *witness);
|
||||||
void witness_assert_not_owner(tsdn_t *tsdn, const witness_t *witness);
|
void witness_assert_not_owner(tsdn_t *tsdn, const witness_t *witness);
|
||||||
void witness_assert_lockless(tsdn_t *tsdn);
|
void witness_assert_lockless(tsdn_t *tsdn);
|
||||||
@ -116,12 +117,25 @@ void witness_unlock(tsdn_t *tsdn, witness_t *witness);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_MUTEX_C_))
|
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_MUTEX_C_))
|
||||||
|
JEMALLOC_INLINE bool
|
||||||
|
witness_owner(tsd_t *tsd, const witness_t *witness)
|
||||||
|
{
|
||||||
|
witness_list_t *witnesses;
|
||||||
|
witness_t *w;
|
||||||
|
|
||||||
|
witnesses = tsd_witnessesp_get(tsd);
|
||||||
|
ql_foreach(w, witnesses, link) {
|
||||||
|
if (w == witness)
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
JEMALLOC_INLINE void
|
JEMALLOC_INLINE void
|
||||||
witness_assert_owner(tsdn_t *tsdn, const witness_t *witness)
|
witness_assert_owner(tsdn_t *tsdn, const witness_t *witness)
|
||||||
{
|
{
|
||||||
tsd_t *tsd;
|
tsd_t *tsd;
|
||||||
witness_list_t *witnesses;
|
|
||||||
witness_t *w;
|
|
||||||
|
|
||||||
if (!config_debug)
|
if (!config_debug)
|
||||||
return;
|
return;
|
||||||
@ -132,11 +146,8 @@ witness_assert_owner(tsdn_t *tsdn, const witness_t *witness)
|
|||||||
if (witness->rank == WITNESS_RANK_OMIT)
|
if (witness->rank == WITNESS_RANK_OMIT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
witnesses = tsd_witnessesp_get(tsd);
|
if (witness_owner(tsd, witness))
|
||||||
ql_foreach(w, witnesses, link) {
|
return;
|
||||||
if (w == witness)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
witness_owner_error(witness);
|
witness_owner_error(witness);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,10 +249,16 @@ witness_unlock(tsdn_t *tsdn, witness_t *witness)
|
|||||||
if (witness->rank == WITNESS_RANK_OMIT)
|
if (witness->rank == WITNESS_RANK_OMIT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
witness_assert_owner(tsdn, witness);
|
/*
|
||||||
|
* Check whether owner before removal, rather than relying on
|
||||||
witnesses = tsd_witnessesp_get(tsd);
|
* witness_assert_owner() to abort, so that unit tests can test this
|
||||||
ql_remove(witnesses, witness, link);
|
* function's failure mode without causing undefined behavior.
|
||||||
|
*/
|
||||||
|
if (witness_owner(tsd, witness)) {
|
||||||
|
witnesses = tsd_witnessesp_get(tsd);
|
||||||
|
ql_remove(witnesses, witness, link);
|
||||||
|
} else
|
||||||
|
witness_assert_owner(tsdn, witness);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user