Parcourir la source

[2205] cover the case where Thread.wait() throws.

JINMEI Tatuya il y a 12 ans
Parent
commit
5bf4005eb7

+ 2 - 0
src/bin/auth/auth_messages.mes

@@ -280,3 +280,5 @@ NOTIFY request will not be honored.
 % AUTH_DATASRC_CLIENTS_BUILDER_FAILED data source builder thread stopped due to an exception: %1
 
 % AUTH_DATASRC_CLIENTS_BUILDER_FAILED_UNEXPECTED data source builder thread stopped due to an unexpected exception
+
+% AUTH_DATASRC_CLIENTS_SHUTDOWN_ERROR error on waiting for data source builder thread: %1

+ 6 - 1
src/bin/auth/datasrc_clients_mgr.h

@@ -100,7 +100,12 @@ public:
     }
     void shutdown() {
         sendCommand(internal::SHUTDOWN, data::ConstElementPtr());
-        builder_thread_->wait();
+        try {
+            builder_thread_->wait();
+        } catch (const util::thread::Thread::UncaughtException& ex) {
+            LOG_ERROR(auth_logger, AUTH_DATASRC_CLIENTS_SHUTDOWN_ERROR).
+                arg(ex.what());
+        }
         builder_thread_.reset();
     }
 

+ 10 - 1
src/bin/auth/tests/datasrc_clients_mgr_unittest.cc

@@ -67,9 +67,18 @@ TEST(DataSrcClientsMgrTest, shutdown) {
     EXPECT_TRUE(FakeDataSrcClientsBuilder::thread_waited);
 }
 
+TEST(DataSrcClientsMgrTest, shutdownWithUncaughtException) {
+    // Emulating the case when the builder exists on exception.  shutdown()
+    // will encounter UncaughtException exception and catch it.
+    TestDataSrcClientsMgr mgr;
+    FakeDataSrcClientsBuilder::thread_throw_on_wait =
+        FakeDataSrcClientsBuilder::THROW_UNCAUGHT_EX;
+    EXPECT_NO_THROW(mgr.shutdown());
+}
 TEST(DataSrcClientsMgrTest, shutdownWithException) {
     TestDataSrcClientsMgr mgr;
-    FakeDataSrcClientsBuilder::thread_throw_on_wait = true;
+    FakeDataSrcClientsBuilder::thread_throw_on_wait =
+        FakeDataSrcClientsBuilder::THROW_OTHER;
     EXPECT_THROW(mgr.shutdown(), isc::Unexpected);
 }
 

+ 3 - 1
src/bin/auth/tests/test_datasrc_clients_mgr.cc

@@ -24,7 +24,9 @@ std::list<internal::Command>* FakeDataSrcClientsBuilder::command_queue = NULL;
 internal::TestCondVar* FakeDataSrcClientsBuilder::cond = NULL;
 internal::TestMutex* FakeDataSrcClientsBuilder::queue_mutex = NULL;
 bool FakeDataSrcClientsBuilder::thread_waited = false;
-bool FakeDataSrcClientsBuilder::thread_throw_on_wait = false;
+FakeDataSrcClientsBuilder::ExceptionFromWait
+FakeDataSrcClientsBuilder::thread_throw_on_wait =
+    FakeDataSrcClientsBuilder::NOTHROW;
 
 namespace internal {
 template<>

+ 23 - 17
src/bin/auth/tests/test_datasrc_clients_mgr.h

@@ -114,21 +114,6 @@ TestDataSrcClientsBuilder::doNoop();
 // possible compromise.
 class FakeDataSrcClientsBuilder {
 public:
-    FakeDataSrcClientsBuilder(std::list<internal::Command>* command_queue,
-                              internal::TestCondVar* cond,
-                              internal::TestMutex* queue_mutex)
-    {
-        FakeDataSrcClientsBuilder::started = false;
-        FakeDataSrcClientsBuilder::command_queue = command_queue;
-        FakeDataSrcClientsBuilder::cond = cond;
-        FakeDataSrcClientsBuilder::queue_mutex = queue_mutex;
-        FakeDataSrcClientsBuilder::thread_waited = false;
-        FakeDataSrcClientsBuilder::thread_throw_on_wait = false;
-    }
-    void run() {
-        FakeDataSrcClientsBuilder::started = true;
-    }
-
     // true iff a builder has started.
     static bool started;
 
@@ -142,7 +127,23 @@ public:
 
     // If set to true by a test, TestThread::wait() throws an exception
     // exception.
-    static bool thread_throw_on_wait;
+    enum ExceptionFromWait { NOTHROW, THROW_UNCAUGHT_EX, THROW_OTHER };
+    static ExceptionFromWait thread_throw_on_wait;
+
+    FakeDataSrcClientsBuilder(std::list<internal::Command>* command_queue,
+                              internal::TestCondVar* cond,
+                              internal::TestMutex* queue_mutex)
+    {
+        FakeDataSrcClientsBuilder::started = false;
+        FakeDataSrcClientsBuilder::command_queue = command_queue;
+        FakeDataSrcClientsBuilder::cond = cond;
+        FakeDataSrcClientsBuilder::queue_mutex = queue_mutex;
+        FakeDataSrcClientsBuilder::thread_waited = false;
+        FakeDataSrcClientsBuilder::thread_throw_on_wait = NOTHROW;
+    }
+    void run() {
+        FakeDataSrcClientsBuilder::started = true;
+    }
 };
 
 class TestThread {
@@ -152,7 +153,12 @@ public:
     }
     void wait() {
         FakeDataSrcClientsBuilder::thread_waited = true;
-        if (FakeDataSrcClientsBuilder::thread_throw_on_wait) {
+        switch (FakeDataSrcClientsBuilder::thread_throw_on_wait) {
+        case FakeDataSrcClientsBuilder::NOTHROW:
+            break;
+        case FakeDataSrcClientsBuilder::THROW_UNCAUGHT_EX:
+            isc_throw(util::thread::Thread::UncaughtException, "for test");
+        case FakeDataSrcClientsBuilder::THROW_OTHER:
             isc_throw(Unexpected, "for test");
         }
     }