#include <gtest/gtest.h>
+#include <exceptions/exceptions.h>
#include <util/thread_pool.h>
#include <boost/function.hpp>
+using namespace isc;
using namespace isc::util;
using namespace std;
// add items to stopped thread pool
for (uint32_t i = 0; i < items_count; ++i) {
- thread_pool.add(make_shared<CallBack>(call_back));
+ EXPECT_NO_THROW(thread_pool.add(make_shared<CallBack>(call_back)));
}
// the item count should match
ASSERT_EQ(thread_pool.count(), items_count);
// calling reset should clear all threads and should remove all queued items
- thread_pool.reset();
+ EXPECT_NO_THROW(thread_pool.reset());
// the item count should be 0
ASSERT_EQ(thread_pool.count(), 0);
// the thread count should be 0
call_back = std::bind(&ThreadPoolTest::runAndWait, this);
// calling start should create the threads and should keep the queued items
- thread_pool.start(thread_count);
+ EXPECT_THROW(thread_pool.start(0), InvalidParameter);
+ // calling start should create the threads and should keep the queued items
+ EXPECT_NO_THROW(thread_pool.start(thread_count));
// the item count should be 0
ASSERT_EQ(thread_pool.count(), 0);
// the thread count should match
ASSERT_EQ(thread_pool.size(), thread_count);
// do it once again to check if it works
- thread_pool.start(thread_count);
+ EXPECT_THROW(thread_pool.start(thread_count), InvalidOperation);
// the item count should be 0
ASSERT_EQ(thread_pool.count(), 0);
// the thread count should match
ASSERT_EQ(thread_pool.size(), thread_count);
// calling stop should clear all threads and should keep queued items
- thread_pool.stop();
+ EXPECT_NO_THROW(thread_pool.stop());
// the item count should be 0
ASSERT_EQ(thread_pool.count(), 0);
// the thread count should be 0
ASSERT_EQ(thread_pool.size(), 0);
// do it once again to check if it works
- thread_pool.stop();
+ EXPECT_THROW(thread_pool.stop(), InvalidOperation);
// the item count should be 0
ASSERT_EQ(thread_pool.count(), 0);
// the thread count should be 0
// add items to stopped thread pool
for (uint32_t i = 0; i < items_count; ++i) {
- thread_pool.add(make_shared<CallBack>(call_back));
+ EXPECT_NO_THROW(thread_pool.add(make_shared<CallBack>(call_back)));
}
// the item count should match
ASSERT_EQ(thread_pool.size(), 0);
// calling stop should clear all threads and should keep queued items
- thread_pool.stop();
+ EXPECT_THROW(thread_pool.stop(), InvalidOperation);
// the item count should match
ASSERT_EQ(thread_pool.count(), items_count);
// the thread count should be 0
ASSERT_EQ(thread_pool.size(), 0);
// calling reset should clear all threads and should remove all queued items
- thread_pool.reset();
+ EXPECT_NO_THROW(thread_pool.reset());
// the item count should be 0
ASSERT_EQ(thread_pool.count(), 0);
// the thread count should be 0
ASSERT_EQ(thread_pool.size(), 0);
// do it once again to check if it works
- thread_pool.reset();
+ EXPECT_NO_THROW(thread_pool.reset());
// the item count should be 0
ASSERT_EQ(thread_pool.count(), 0);
// the thread count should be 0
ASSERT_EQ(thread_pool.size(), 0);
// calling start should create the threads and should keep the queued items
- thread_pool.start(thread_count);
+ EXPECT_NO_THROW(thread_pool.start(thread_count));
// the item count should be 0
ASSERT_EQ(thread_pool.count(), 0);
// the thread count should be 0
// add items to running thread pool
for (uint32_t i = 0; i < items_count; ++i) {
- thread_pool.add(make_shared<CallBack>(call_back));
+ EXPECT_NO_THROW(thread_pool.add(make_shared<CallBack>(call_back)));
}
// wait for all items to be processed
signalThreads();
// calling stop should clear all threads and should keep queued items
- thread_pool.stop();
+ EXPECT_NO_THROW(thread_pool.stop());
// the item count should be 0
ASSERT_EQ(thread_pool.count(), 0);
// the thread count should be 0
// add items to stopped thread pool
for (uint32_t i = 0; i < items_count; ++i) {
- thread_pool.add(make_shared<CallBack>(call_back));
+ EXPECT_NO_THROW(thread_pool.add(make_shared<CallBack>(call_back)));
}
// the item count should match
ASSERT_EQ(thread_pool.size(), 0);
// calling start should create the threads and should keep the queued items
- thread_pool.start(thread_count);
+ EXPECT_NO_THROW(thread_pool.start(thread_count));
// the thread count should match
ASSERT_EQ(thread_pool.size(), thread_count);
checkRunHistory(items_count);
// calling stop should clear all threads and should keep queued items
- thread_pool.stop();
+ EXPECT_NO_THROW(thread_pool.stop());
// the item count should be 0
ASSERT_EQ(thread_pool.count(), 0);
// the thread count should be 0
/// @brief reset the thread pool stopping threads and clearing the internal
/// queue
+ ///
+ /// It can be called several times even when the thread pool is stopped
void reset() {
- stop();
+ stopInternal();
queue_.clear();
}
///
/// @param thread_count specifies the number of threads to be created and
/// started
+ ///
+ /// @throw InvalidOperation if thread pool already started
+ /// @throw InvalidParameter if thread count is 0
void start(uint32_t thread_count) {
if (!thread_count) {
isc_throw(InvalidParameter, "thread count is 0");
}
if (running_) {
- isc_throw(InvalidParameter, "thread pool already started");
+ isc_throw(InvalidOperation, "thread pool already started");
}
+ startInternal(thread_count);
+ }
+
+ /// @brief start all the threads
+ ///
+ /// @param thread_count specifies the number of threads to be created and
+ /// started
+ void startInternal(uint32_t thread_count) {
queue_.enable();
running_ = true;
for (uint32_t i = 0; i < thread_count; ++i) {
}
/// @brief stop all the threads
+ ///
+ /// @throw InvalidOperation if thread pool already stopped
void stop() {
if (!running_) {
- isc_throw(InvalidParameter, "thread pool already stopped");
+ isc_throw(InvalidOperation, "thread pool already stopped");
}
+ stopInternal();
+ }
+
+ /// @brief stop all the threads
+ void stopInternal() {
running_ = false;
queue_.disable();
for (auto thread : threads_) {
/// Removes all queued work items
void clear() {
std::lock_guard<std::mutex> lock(mutex_);
- queue_ = std::queue<Item>();
+ queue_ = QueueContainer();
}
/// @brief enable the queue
try {
(*item)();
} catch (...) {
+ // catch all exceptions
}
}
}