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_;
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
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<>
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,
// 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_;
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 {
TestThread(const boost::function<void()>& main) {
main();
}
+ void wait() {
+ FakeDataSrcClientsBuilder::thread_waited = true;
+ }
};
// Convenient shortcut