EXPECT_EQ(3, FakeDataSrcClientsBuilder::command_queue->size());
}
+void
+callback(bool* called, int *tag_target, int tag_value) {
+ *called = true;
+ *tag_target = tag_value;
+}
+
+// Test we can wake up the main thread by writing to the file descriptor and
+// that the callbacks are executed and removed when woken up.
+TEST(DataSrcClientsMgrTest, wakeup) {
+ bool called = false;
+ int tag;
+ {
+ TestDataSrcClientsMgr mgr;
+ // There's some real file descriptor (or something that looks so)
+ ASSERT_GT(FakeDataSrcClientsBuilder::wakeup_fd, 0);
+ // Push a callback in and wake the manager
+ FakeDataSrcClientsBuilder::callback_queue->
+ push_back(boost::bind(callback, &called, &tag, 1));
+ write(FakeDataSrcClientsBuilder::wakeup_fd, "w", 1);
+ mgr.run_one();
+ EXPECT_TRUE(called);
+ EXPECT_EQ(1, tag);
+ EXPECT_TRUE(FakeDataSrcClientsBuilder::callback_queue->empty());
+
+ called = false;
+ // If we wake up and don't push anything, it doesn't break.
+ write(FakeDataSrcClientsBuilder::wakeup_fd, "w", 1);
+ mgr.run_one();
+ EXPECT_FALSE(called);
+
+ // When we terminate, it should process whatever is left
+ // of the callbacks. So push and terminate (and don't directly
+ // wake).
+ FakeDataSrcClientsBuilder::callback_queue->
+ push_back(boost::bind(callback, &called, &tag, 2));
+ }
+ EXPECT_TRUE(called);
+ EXPECT_EQ(2, tag);
+ EXPECT_TRUE(FakeDataSrcClientsBuilder::callback_queue->empty());
+}
+
TEST(DataSrcClientsMgrTest, realThread) {
// Using the non-test definition with a real thread. Just checking
// no disruption happens.
// Define static DataSrcClientsBuilder member variables.
bool FakeDataSrcClientsBuilder::started = false;
std::list<Command>* FakeDataSrcClientsBuilder::command_queue = NULL;
+std::list<FinishedCallback>* FakeDataSrcClientsBuilder::callback_queue = NULL;
std::list<Command> FakeDataSrcClientsBuilder::command_queue_copy;
+std::list<FinishedCallback> FakeDataSrcClientsBuilder::callback_queue_copy;
TestCondVar* FakeDataSrcClientsBuilder::cond = NULL;
TestCondVar FakeDataSrcClientsBuilder::cond_copy;
TestMutex* FakeDataSrcClientsBuilder::queue_mutex = NULL;
FakeDataSrcClientsBuilder::ExceptionFromWait
FakeDataSrcClientsBuilder::thread_throw_on_wait =
FakeDataSrcClientsBuilder::NOTHROW;
+int FakeDataSrcClientsBuilder::wakeup_fd = -1;
template<>
void
FakeDataSrcClientsBuilder::cond_copy = cond_;
FakeDataSrcClientsBuilder::cond =
&FakeDataSrcClientsBuilder::cond_copy;
+ FakeDataSrcClientsBuilder::callback_queue_copy =
+ *FakeDataSrcClientsBuilder::callback_queue;
+ FakeDataSrcClientsBuilder::callback_queue =
+ &FakeDataSrcClientsBuilder::callback_queue_copy;
}
template<>
// true iff a builder has started.
static bool started;
- // These three correspond to the resource shared with the manager.
+ // These five correspond to the resource shared with the manager.
// xxx_copy will be set in the manager's destructor to record the
// final state of the manager.
static std::list<Command>* command_queue;
+ static std::list<FinishedCallback>* callback_queue;
static TestCondVar* cond;
static TestMutex* queue_mutex;
+ static int wakeup_fd;
static isc::datasrc::ClientListMapPtr* clients_map;
static TestMutex* map_mutex;
static std::list<Command> command_queue_copy;
+ static std::list<FinishedCallback> callback_queue_copy;
static TestCondVar cond_copy;
static TestMutex queue_mutex_copy;
FakeDataSrcClientsBuilder(
std::list<Command>* command_queue,
- std::list<FinishedCallback>*,
+ std::list<FinishedCallback>* callback_queue,
TestCondVar* cond,
TestMutex* queue_mutex,
isc::datasrc::ClientListMapPtr* clients_map,
- TestMutex* map_mutex, int)
+ TestMutex* map_mutex, int wakeup_fd)
{
FakeDataSrcClientsBuilder::started = false;
FakeDataSrcClientsBuilder::command_queue = command_queue;
+ FakeDataSrcClientsBuilder::callback_queue = callback_queue;
FakeDataSrcClientsBuilder::cond = cond;
FakeDataSrcClientsBuilder::queue_mutex = queue_mutex;
+ FakeDataSrcClientsBuilder::wakeup_fd = wakeup_fd;
FakeDataSrcClientsBuilder::clients_map = clients_map;
FakeDataSrcClientsBuilder::map_mutex = map_mutex;
FakeDataSrcClientsBuilder::thread_waited = false;