We move on to designing the ThreadPool class. Before we introduce threads, we test-drive some building blocks for handling requests.
c9/5/ThreadPoolTest.cpp | |
| #include "CppUTest/TestHarness.h" |
| #include "ThreadPool.h" |
| |
| using namespace std; |
| |
| TEST_GROUP(AThreadPool) { |
| ThreadPool pool; |
| }; |
| |
| TEST(AThreadPool, HasNoWorkOnCreation) { |
| CHECK_FALSE(pool.hasWork()); |
| } |
| |
| TEST(AThreadPool, HasWorkAfterAdd) { |
| pool.add(Work{}); |
| CHECK_TRUE(pool.hasWork()); |
| } |
| |
| TEST(AThreadPool, AnswersWorkAddedOnPull) { |
| pool.add(Work{1}); |
| auto work = pool.pullWork(); |
| |
| LONGS_EQUAL(1, work.id()); |
| } |
| |
| TEST(AThreadPool, PullsElementsInFIFOOrder) { |
| pool.add(Work{1}); |
| pool.add(Work{2}); |
| auto work = pool.pullWork(); |
| |
| LONGS_EQUAL(1, work.id()); |
| } |
| |
| TEST(AThreadPool, HasNoWorkAfterLastElementRemoved) { |
| pool.add(Work{}); |
| pool.pullWork(); |
| CHECK_FALSE(pool.hasWork()); |
| } |
| |
| TEST(AThreadPool, HasWorkAfterWorkRemovedButWorkRemains) { |
| pool.add(Work{}); |
| pool.add(Work{}); |
| pool.pullWork(); |
| CHECK_TRUE(pool.hasWork()); |
| } |
c9/5/ThreadPool.h | |
| #ifndef ThreadPool_h |
| #define ThreadPool_h |
| |
| #include <string> |
| #include <deque> |
| #include "Work.h" |
| |
| class ThreadPool { |
| public: |
| bool hasWork() { |
| return !workQueue_.empty(); |
| } |
| |
| void add(Work work) { |
| workQueue_.push_front(work); |
| } |
| |
| Work pullWork() { |
| auto work = workQueue_.back(); |
| workQueue_.pop_back(); |
| return work; |
| } |
| |
| private: |
| std::deque<Work> workQueue_; |
| }; |
| #endif |
The test AnswersWorkAddedOnPull must verify that work pulled matches the same work added. We might have compared addresses, but we decide to make our tests easier by supporting an ID for Work objects.
c9/5/Work.h | |
| #ifndef Work_h |
| #define Work_h |
| #include <functional> |
| |
| class Work { |
| public: |
| static const int DefaultId{0}; |
| Work(int id=DefaultId) |
| : id_{id} |
| , executeFunction_{[]{}} {} |
| Work(std::function<void()> executeFunction, int id=DefaultId) |
| : id_{id} |
| , executeFunction_{executeFunction} |
| {} |
| void execute() { |
| executeFunction_(); |
| } |
| int id() const { |
| return id_; |
| } |
| private: |
| int id_; |
| std::function<void()> executeFunction_; |
| }; |
| #endif |
3.136.22.179