Scroom  0.14
threadpool-queue-tests.cc File Reference
#include <scroom/threadpool.hh>
#include <iostream>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/thread.hpp>
#include <scroom/function-additor.hh>
#include <scroom/semaphore.hh>
#include "helpers.hh"
#include "queue.hh"
Include dependency graph for threadpool-queue-tests.cc:

Functions

const millisec short_timeout (250)
 
const millisec long_timeout (2000)
 
 BOOST_AUTO_TEST_CASE (basic_jobcounting)
 
 BOOST_AUTO_TEST_CASE (destroy_waits_for_jobs_to_finish)
 
 BOOST_AUTO_TEST_CASE (destroy_using_QueueLock)
 
 BOOST_AUTO_TEST_CASE (jobs_on_custom_queue_get_executed)
 
 BOOST_AUTO_TEST_CASE (jobs_on_deleted_queue_dont_get_executed)
 
 BOOST_AUTO_TEST_CASE (queue_deletion_waits_for_jobs_to_finish)
 

Function Documentation

◆ BOOST_AUTO_TEST_CASE() [1/6]

BOOST_AUTO_TEST_CASE ( basic_jobcounting  )
40 {
41  QueueImpl::Ptr const queue = QueueImpl::create();
42  BOOST_CHECK(queue);
43  BOOST_CHECK_EQUAL(0, queue->getCount());
44  queue->jobStarted();
45  BOOST_CHECK_EQUAL(1, queue->getCount());
46  queue->jobStarted();
47  BOOST_CHECK_EQUAL(2, queue->getCount());
48  queue->jobFinished();
49  BOOST_CHECK_EQUAL(1, queue->getCount());
50  queue->jobFinished();
51  BOOST_CHECK_EQUAL(0, queue->getCount());
52 }
Here is the call graph for this function:

◆ BOOST_AUTO_TEST_CASE() [2/6]

BOOST_AUTO_TEST_CASE ( destroy_using_QueueLock  )
89 {
91  ThreadPool::Queue::WeakPtr const weakQueue = queue;
92  BOOST_CHECK(queue);
93  auto* l = new QueueLock(queue->get());
94 
95  Semaphore s0(0);
96  Semaphore s1(0);
97  Semaphore s2(0);
98  boost::thread const t(clear(&s0) + pass(&s1) + destroy(queue) + clear(&s2));
99  s0.P();
101  queue.reset();
102  BOOST_CHECK(weakQueue.lock());
103  s1.V();
104  BOOST_REQUIRE(!s2.P(long_timeout));
105  BOOST_CHECK(!weakQueue.lock());
106 
107  // At this point, all references to ThreadPool::Queue are gone, but the thread
108  // trying to destroy it is blocked because
109  // not all jobs have finished yet. So we should report the jobs complete,
110  // and then the thread will unblock and the object will actually be deleted.
111  delete l;
113 }
Here is the call graph for this function:

◆ BOOST_AUTO_TEST_CASE() [3/6]

BOOST_AUTO_TEST_CASE ( destroy_waits_for_jobs_to_finish  )
55 {
57  ThreadPool::Queue::WeakPtr const weakQueue = queue;
58  QueueImpl::Ptr const qi = queue->get();
59  BOOST_CHECK(queue);
60  BOOST_CHECK(qi);
61  BOOST_CHECK_EQUAL(0, qi->getCount());
62  qi->jobStarted();
63  BOOST_CHECK_EQUAL(1, qi->getCount());
64  qi->jobStarted();
65  BOOST_CHECK_EQUAL(2, qi->getCount());
66 
67  Semaphore const s0(0);
68  Semaphore s1(0);
69  Semaphore s2(0);
70  boost::thread const t(pass(&s1) + destroy(queue) + clear(&s2));
71  queue.reset();
72  BOOST_CHECK(weakQueue.lock());
73  s1.V();
75  BOOST_CHECK(!weakQueue.lock());
76 
77  // At this point, all references to ThreadPool::Queue are gone, but the thread
78  // trying to destroy it is blocked because
79  // not all jobs have finished yet. So we should report the jobs complete,
80  // and then the thread will unblock and the object will actually be deleted.
81  qi->jobFinished();
83  BOOST_CHECK_EQUAL(1, qi->getCount());
84  qi->jobFinished();
86 }
Here is the call graph for this function:

◆ BOOST_AUTO_TEST_CASE() [4/6]

BOOST_AUTO_TEST_CASE ( jobs_on_custom_queue_get_executed  )
120 {
122  Semaphore s(0);
123  ThreadPool t(0);
124  t.schedule(clear(&s), queue);
125  t.add();
126  BOOST_CHECK(s.P(long_timeout));
127 }
Here is the call graph for this function:

◆ BOOST_AUTO_TEST_CASE() [5/6]

BOOST_AUTO_TEST_CASE ( jobs_on_deleted_queue_dont_get_executed  )
130 {
132  Semaphore s1(0);
133  Semaphore s2(0);
134  ThreadPool t(0);
135  t.schedule(clear(&s1), queue);
136  t.schedule(clear(&s2));
137  queue.reset();
138  t.add();
139  BOOST_CHECK(s2.P(long_timeout));
140  BOOST_CHECK(!s1.try_P());
141 }
Here is the call graph for this function:

◆ BOOST_AUTO_TEST_CASE() [6/6]

BOOST_AUTO_TEST_CASE ( queue_deletion_waits_for_jobs_to_finish  )
144 {
146  ThreadPool::Queue::WeakPtr const weakQueue = queue;
147  Semaphore const s0(0);
148  Semaphore s1(0);
149  Semaphore s2(0);
150  Semaphore s3(0);
151  Semaphore s4(0);
152 
153  ThreadPool pool(0);
154  pool.schedule(clear(&s1) + pass(&s2), queue);
155  pool.add();
157  // Job is now being executed, hence it should not be possible to delete the queue
158 
159  // Setup: Create a thread that will delete the queue. Then delete our
160  // reference, because if our reference is the last, our thread will block,
161  // resulting in deadlock
162  boost::thread const t(pass(&s3) + destroy(queue) + clear(&s4));
163  queue.reset();
164 
165  // Tell the thread to start deleting the Queue
166  s3.V();
167  // Thread does not finish
168  BOOST_CHECK(!s4.P(long_timeout));
169 
170  // Complete the job
171  s2.V();
172  // Thread now finishes throwing away the Queue
173  BOOST_CHECK(s4.P(long_timeout));
174 }
Here is the call graph for this function:

◆ long_timeout()

const millisec long_timeout ( 2000  )

Referenced by BOOST_AUTO_TEST_CASE().

Here is the caller graph for this function:

◆ short_timeout()

const millisec short_timeout ( 250  )

Referenced by BOOST_AUTO_TEST_CASE().

Here is the caller graph for this function:
ThreadPool::Queue::Ptr
boost::shared_ptr< Queue > Ptr
Definition: threadpool.hh:82
clear
boost::function< void()> clear(Semaphore *s)
Definition: helpers.cc:29
ThreadPool
Definition: threadpool.hh:46
BOOST_CHECK_EQUAL
BOOST_CHECK_EQUAL(sample.expectedColors, originalColormap->colors.size())
destroy
boost::function< void()> destroy(boost::shared_ptr< void > p)
Definition: helpers.cc:31
ThreadPool::Queue::create
static Ptr create()
ThreadPool::Queue.
Definition: threadpoolimpl.cc:377
long_timeout
const millisec long_timeout(2000)
Scroom::Semaphore
Definition: semaphore.hh:15
Scroom::Detail::ThreadPool::QueueLock
Definition: queue.hh:63
Scroom::Detail::ThreadPool::QueueImpl::Ptr
boost::shared_ptr< QueueImpl > Ptr
Definition: queue.hh:25
BOOST_REQUIRE
BOOST_REQUIRE(originalColormap)
pass
boost::function< void()> pass(Semaphore *s)
Definition: helpers.cc:27
short_timeout
const millisec short_timeout(250)
ThreadPool::Queue::WeakPtr
boost::weak_ptr< Queue > WeakPtr
Definition: threadpool.hh:83
create
void create(NewPresentationInterface *interface)
Definition: loader.cc:175