Browse Source

[2205] supported manager's shutdown command

JINMEI Tatuya 12 years ago
parent
commit
d2009fd950

+ 7 - 2
src/bin/auth/datasrc_clients_mgr.h

@@ -78,11 +78,16 @@ public:
         builder_thread_(boost::bind(&BuilderType::run, &builder_))
     {}
     ~DataSrcClientsMgrBase() {}
-#ifdef notyet
     void shutdown() {
+        {
+            using namespace internal;
+            typename MutexType::Locker locker(queue_mutex_);
+            command_queue_.push_back(Command(SHUTDOWN,
+                                             data::ConstElementPtr()));
+        }
+        cond_.signal();
         builder_thread_.wait();
     }
-#endif
 
 private:
     std::list<internal::Command> command_queue_;

+ 22 - 0
src/bin/auth/tests/datasrc_clients_mgr_unittest.cc

@@ -36,4 +36,26 @@ TEST_F(DataSrcClientsMgrTest, start) {
     EXPECT_TRUE(FakeDataSrcClientsBuilder::command_queue->empty());
 }
 
+TEST_F(DataSrcClientsMgrTest, shutdown) {
+    // Invoke shutdown on the manager.
+    TestDataSrcClientsMgr mgr;
+    EXPECT_TRUE(FakeDataSrcClientsBuilder::started);
+
+    // Check pre-command conditions
+    EXPECT_EQ(0, FakeDataSrcClientsBuilder::cond->signal_count);
+    EXPECT_FALSE(FakeDataSrcClientsBuilder::thread_waited);
+
+    mgr.shutdown();
+
+    // The manager should have acquired the lock, put a SHUTDOWN command
+    // to the queue, and should have signaled the builder.
+    EXPECT_EQ(1, FakeDataSrcClientsBuilder::queue_mutex->lock_count);
+    EXPECT_EQ(1, FakeDataSrcClientsBuilder::cond->signal_count);
+    EXPECT_EQ(1, FakeDataSrcClientsBuilder::command_queue->size());
+    const Command& cmd = FakeDataSrcClientsBuilder::command_queue->front();
+    EXPECT_EQ(SHUTDOWN, cmd.first);
+    EXPECT_FALSE(cmd.second);
+    EXPECT_TRUE(FakeDataSrcClientsBuilder::thread_waited);
+}
+
 } // unnamed namespace

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

@@ -21,6 +21,7 @@ bool FakeDataSrcClientsBuilder::started = false;
 std::list<internal::Command>* FakeDataSrcClientsBuilder::command_queue = NULL;
 internal::TestCondVar* FakeDataSrcClientsBuilder::cond = NULL;
 internal::TestMutex* FakeDataSrcClientsBuilder::queue_mutex = NULL;
+bool FakeDataSrcClientsBuilder::thread_waited = false;
 
 namespace internal {
 template<>

+ 15 - 1
src/bin/auth/tests/test_datasrc_clients_mgr.h

@@ -47,7 +47,7 @@ public:
 
 class TestCondVar {
 public:
-    TestCondVar() : wait_count(0), command_queue_(NULL),
+    TestCondVar() : wait_count(0), signal_count(0), command_queue_(NULL),
                     delayed_command_queue_(NULL)
     {}
     TestCondVar(std::list<Command>& command_queue,
@@ -66,7 +66,11 @@ public:
         // make the delayed commands available
         command_queue_->splice(command_queue_->end(), *delayed_command_queue_);
     }
+    void signal() {
+        ++signal_count;
+    }
     size_t wait_count;
+    size_t signal_count;
 private:
     std::list<Command>* command_queue_;
     std::list<Command>* delayed_command_queue_;
@@ -98,15 +102,22 @@ public:
         FakeDataSrcClientsBuilder::command_queue = command_queue;
         FakeDataSrcClientsBuilder::cond = cond;
         FakeDataSrcClientsBuilder::queue_mutex = queue_mutex;
+        FakeDataSrcClientsBuilder::thread_waited = false;
     }
     void run() {
         FakeDataSrcClientsBuilder::started = true;
     }
 
+    // true iff a builder has started.
     static bool started;
+
+    // These three correspond to the resource shared with the manager.
     static std::list<internal::Command>* command_queue;
     static internal::TestCondVar* cond;
     static internal::TestMutex* queue_mutex;
+
+    // true iff the manager waited on the thread running the builder.
+    static bool thread_waited;
 };
 
 class TestThread {
@@ -114,6 +125,9 @@ public:
     TestThread(const boost::function<void()>& main) {
         main();
     }
+    void wait() {
+        FakeDataSrcClientsBuilder::thread_waited = true;
+    }
 };
 
 // Convenient shortcut