BIND 10 master, updated. 653d1d854ad6574806ed09f6b42aaa4a17f27b57 Merge branch 'master' into trac2236
BIND 10 source code commits
bind10-changes at lists.isc.org
Thu Oct 25 23:48:36 UTC 2012
The branch, master has been updated
via 653d1d854ad6574806ed09f6b42aaa4a17f27b57 (commit)
via 54ae641d1c1fa87baeb702ec0ee25b28c2b7aebd (commit)
via 1d4d9e796c10786417099a69e8c4e6e4c1cdfb8b (commit)
via 7c4e02c157bf7a4baaa81c448ff485e7dec31182 (commit)
via 2eaf01995b4c0d6c007afd51c94b8453cbb797ca (commit)
via 8b19f3a80a57b4a0c41e58460920924d5613e606 (commit)
via 98db15a31fea52ec2b1952846c61d20f9f373305 (commit)
via 4f4b3724e1e06933646dcbee14f31eb2713a514d (commit)
via fa78c4ba3aff851955576ec7e98f8fe98dacd889 (commit)
via 149df5a690bc874b8814669c19a8666e2cddf961 (commit)
via 2a6f0764001c25acb40eae27d7a2f7691d4c767b (commit)
via 4887037cd08e567596339dbb3d65557b8e25560d (commit)
from c7123c288ebc9a1ac9aa86c43219877c86a6a032 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 653d1d854ad6574806ed09f6b42aaa4a17f27b57
Merge: 54ae641 c7123c2
Author: Mukund Sivaraman <muks at isc.org>
Date: Fri Oct 26 04:24:07 2012 +0530
Merge branch 'master' into trac2236
Conflicts:
src/bin/auth/auth_srv.cc
src/bin/auth/tests/auth_srv_unittest.cc
-----------------------------------------------------------------------
Summary of changes:
configure.ac | 15 +++++
src/lib/util/threads/sync.cc | 77 ++++++++++++++++--------
src/lib/util/threads/sync.h | 6 ++
src/lib/util/threads/tests/condvar_unittest.cc | 4 ++
src/lib/util/threads/tests/lock_unittest.cc | 12 +++-
5 files changed, 86 insertions(+), 28 deletions(-)
-----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 32f81b3..5bbba16 100644
--- a/configure.ac
+++ b/configure.ac
@@ -12,6 +12,20 @@ AC_CONFIG_MACRO_DIR([m4macros])
# Checks for programs.
AC_PROG_CXX
+# Enable low-performing debugging facilities? This option optionally
+# enables some debugging aids that perform slowly and hence aren't built
+# by default.
+AC_ARG_ENABLE([debug],
+ AS_HELP_STRING([--enable-debug],
+ [enable debugging (default is no)]),
+ [case "${enableval}" in
+ yes) debug_enabled=yes ;;
+ no) debug_enabled=no ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for --enable-debug]) ;;
+ esac],[debug_enabled=no])
+AM_CONDITIONAL([DEBUG_ENABLED], [test x$debug_enabled = xyes])
+AM_COND_IF([DEBUG_ENABLED], [AC_DEFINE([ENABLE_DEBUG], [1], [Enable low-performing debugging facilities?])])
+
# Libtool configuration
#
@@ -1422,6 +1436,7 @@ Features:
$enable_features
Developer:
+ Enable Debugging: $debug_enabled
Google Tests: $enable_gtest
Valgrind: $found_valgrind
C++ Code Coverage: $USE_LCOV
diff --git a/src/lib/util/threads/sync.cc b/src/lib/util/threads/sync.cc
index c98a7a6..46a5646 100644
--- a/src/lib/util/threads/sync.cc
+++ b/src/lib/util/threads/sync.cc
@@ -12,6 +12,8 @@
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
+#include "config.h"
+
#include "sync.h"
#include <exceptions/exceptions.h>
@@ -31,12 +33,16 @@ namespace thread {
class Mutex::Impl {
public:
- Impl() :
- locked_count(0)
+ Impl()
+#ifdef ENABLE_DEBUG
+ : locked_count(0)
+#endif // ENABLE_DEBUG
{}
+
pthread_mutex_t mutex;
- // Only in debug mode
+#ifdef ENABLE_DEBUG
size_t locked_count;
+#endif // ENABLE_DEBUG
};
namespace {
@@ -70,12 +76,20 @@ Mutex::Mutex() :
isc_throw(isc::InvalidOperation, std::strerror(result));
}
Deinitializer deinitializer(attributes);
- // TODO: Distinguish if debug mode is enabled in compilation.
- // If so, it should be PTHREAD_MUTEX_NORMAL or NULL
+
+ // If debug mode is enabled in compilation, use the slower
+ // error-checking mutexes that detect deadlocks. Otherwise, use fast
+ // mutexes which don't. See the pthread_mutexattr_settype() POSIX
+ // documentation which describes these type attributes.
+#ifdef ENABLE_DEBUG
result = pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_ERRORCHECK);
+#else
+ result = pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_NORMAL);
+#endif // ENABLE_DEBUG
if (result != 0) {
isc_throw(isc::InvalidOperation, std::strerror(result));
}
+
auto_ptr<Impl> impl(new Impl);
result = pthread_mutex_init(&impl->mutex, &attributes);
switch (result) {
@@ -93,12 +107,17 @@ Mutex::Mutex() :
Mutex::~Mutex() {
if (impl_ != NULL) {
const int result = pthread_mutex_destroy(&impl_->mutex);
+
+#ifdef ENABLE_DEBUG
const bool locked = impl_->locked_count != 0;
+#endif // ENABLE_DEBUG
+
delete impl_;
// We don't want to throw from the destructor. Also, if this ever
// fails, something is really screwed up a lot.
assert(result == 0);
+#ifdef ENABLE_DEBUG
// We should not try to destroy a locked mutex, bad threaded monsters
// could get loose if we ever do and it is also forbidden by pthreads.
@@ -106,29 +125,19 @@ Mutex::~Mutex() {
// pthread_mutex_destroy should check for it already. But it seems
// there are systems that don't check it.
assert(!locked);
+#endif // ENABLE_DEBUG
}
}
+#ifdef ENABLE_DEBUG
+
void
Mutex::postLockAction() {
- // This assertion would fail only in non-debugging mode, in which case
- // this method wouldn't be called either, so we simply assert the
- // condition.
assert(impl_->locked_count == 0);
++impl_->locked_count;
}
void
-Mutex::lock() {
- assert(impl_ != NULL);
- const int result = pthread_mutex_lock(&impl_->mutex);
- if (result != 0) {
- isc_throw(isc::InvalidOperation, std::strerror(result));
- }
- postLockAction(); // Only in debug mode
-}
-
-void
Mutex::preUnlockAction(bool throw_ok) {
if (impl_->locked_count == 0) {
if (throw_ok) {
@@ -141,20 +150,35 @@ Mutex::preUnlockAction(bool throw_ok) {
--impl_->locked_count;
}
+bool
+Mutex::locked() const {
+ return (impl_->locked_count != 0);
+}
+
+#endif // ENABLE_DEBUG
+
+void
+Mutex::lock() {
+ assert(impl_ != NULL);
+ const int result = pthread_mutex_lock(&impl_->mutex);
+ if (result != 0) {
+ isc_throw(isc::InvalidOperation, std::strerror(result));
+ }
+#ifdef ENABLE_DEBUG
+ postLockAction(); // Only in debug mode
+#endif // ENABLE_DEBUG
+}
+
void
Mutex::unlock() {
assert(impl_ != NULL);
+#ifdef ENABLE_DEBUG
preUnlockAction(false); // Only in debug mode. Ensure no throw.
+#endif // ENABLE_DEBUG
const int result = pthread_mutex_unlock(&impl_->mutex);
assert(result == 0); // This should never be possible
}
-// TODO: Disable in non-debug build
-bool
-Mutex::locked() const {
- return (impl_->locked_count != 0);
-}
-
class CondVar::Impl {
public:
Impl() {
@@ -187,10 +211,13 @@ CondVar::~CondVar() {
void
CondVar::wait(Mutex& mutex) {
+#ifdef ENABLE_DEBUG
mutex.preUnlockAction(true); // Only in debug mode
const int result = pthread_cond_wait(&impl_->cond_, &mutex.impl_->mutex);
mutex.postLockAction(); // Only in debug mode
-
+#else
+ const int result = pthread_cond_wait(&impl_->cond_, &mutex.impl_->mutex);
+#endif
// pthread_cond_wait should normally succeed unless mutex is completely
// broken.
if (result != 0) {
diff --git a/src/lib/util/threads/sync.h b/src/lib/util/threads/sync.h
index ff56999..87c78be 100644
--- a/src/lib/util/threads/sync.h
+++ b/src/lib/util/threads/sync.h
@@ -112,6 +112,9 @@ private:
// Commonly called after acquiring the lock, checking and updating
// internal state for debug.
+ //
+ // Note that this method is only available when the build is
+ // configured with debugging support.
void postLockAction();
// Commonly called before releasing the lock, checking and updating
@@ -121,6 +124,9 @@ private:
// fails; otherwise it aborts the process. This parameter must be set
// to false if the call to this shouldn't result in an exception (e.g.
// when called from a destructor).
+ //
+ // Note that this method is only available when the build is
+ // configured with debugging support.
void preUnlockAction(bool throw_ok);
class Impl;
diff --git a/src/lib/util/threads/tests/condvar_unittest.cc b/src/lib/util/threads/tests/condvar_unittest.cc
index 77a8980..8b1fe54 100644
--- a/src/lib/util/threads/tests/condvar_unittest.cc
+++ b/src/lib/util/threads/tests/condvar_unittest.cc
@@ -149,11 +149,15 @@ TEST_F(CondVarTest, DISABLED_destroyWhileWait) {
}, "");
}
+#ifdef ENABLE_DEBUG
+
TEST_F(CondVarTest, badWait) {
// In our implementation, wait() requires acquiring the lock beforehand.
EXPECT_THROW(condvar_.wait(mutex_), isc::InvalidOperation);
}
+#endif // ENABLE_DEBUG
+
TEST_F(CondVarTest, emptySignal) {
// It's okay to call signal when no one waits.
EXPECT_NO_THROW(condvar_.signal());
diff --git a/src/lib/util/threads/tests/lock_unittest.cc b/src/lib/util/threads/tests/lock_unittest.cc
index 9c17e6f..498d01e 100644
--- a/src/lib/util/threads/tests/lock_unittest.cc
+++ b/src/lib/util/threads/tests/lock_unittest.cc
@@ -26,20 +26,26 @@ using namespace isc::util::thread;
namespace {
-// If we try to lock the debug mutex multiple times, it should throw.
+#ifdef ENABLE_DEBUG
+
+// If we try to lock the debug mutex multiple times, it should
+// throw. This test will complete properly only when pthread debugging
+// facilities are enabled by configuring the code for debug build.
TEST(MutexTest, lockMultiple) {
- // TODO: Once we support non-debug mutexes, disable the test if we compile
- // with them.
Mutex mutex;
EXPECT_FALSE(mutex.locked()); // Debug-only build
+
Mutex::Locker l1(mutex);
EXPECT_TRUE(mutex.locked()); // Debug-only build
+
EXPECT_THROW({
Mutex::Locker l2(mutex); // Attempt to lock again.
}, isc::InvalidOperation);
EXPECT_TRUE(mutex.locked()); // Debug-only build
}
+#endif // ENABLE_DEBUG
+
// Destroying a locked mutex is a bad idea as well
#ifdef EXPECT_DEATH
TEST(MutexTest, destroyLocked) {
More information about the bind10-changes
mailing list