Fawkes API  Fawkes Development Version
test_wait_condition.cpp
1 /***************************************************************************
2  * test_wait_condition.cpp - WaitCondition Unit Test
3  *
4  * Created: Sat Jan 24 15:12:42 2015
5  * Copyright 2015 Till Hofmann
6  *
7  ****************************************************************************/
8 
9 /* This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU Library General Public License for more details.
18  *
19  * Read the full text in the LICENSE.GPL file in the doc directory.
20  */
21 
22 #include <gtest/gtest.h>
23 
24 #include <pthread.h>
25 #ifdef __FreeBSD__
26 # include <pthread_np.h>
27 #endif
28 #include <core/threading/wait_condition.h>
29 
30 #include <time.h>
31 #include <unistd.h>
32 
33 using namespace fawkes;
34 
35 /** The parameters passed to the threads. */
37 {
38  /** The thread's wait condition. */
40 };
41 
42 /** @class WaitConditionTest
43  * Test class for WaitConditions
44  * This class tets basic functionality of WaitConditions,
45  * mainly thread cancellation problems
46  */
47 class WaitConditionTest : public ::testing::Test
48 {
49 protected:
50  WaitConditionTest() : cond(new WaitCondition()), num_threads(2)
51  {
52  }
53  virtual ~WaitConditionTest()
54  {
55  delete cond;
56  }
57 
58  /** Start threads with the given function, cancel the threads
59  * and assert they have terminated.
60  * @param thread_func The function the threads are started with.
61  */
62  void
63  start_test(void *(*thread_func)(void *))
64  {
65  pthread_t threads[num_threads];
66  thread_params *params[num_threads];
67  for (uint i = 0; i < num_threads; i++) {
68  params[i] = new thread_params();
69  params[i]->cond = cond;
70  pthread_create(&threads[i], NULL, thread_func, params[i]);
71  pthread_yield();
72  }
73 
74  usleep(1000);
75  for (uint i = 0; i < num_threads; i++) {
76  pthread_cancel(threads[i]);
77  struct timespec ts;
78  ASSERT_NE(-1, clock_gettime(CLOCK_REALTIME, &ts));
79  // give the thread two seconds to terminate
80  ts.tv_sec += 2;
81  ASSERT_EQ(0, pthread_timedjoin_np(threads[i], NULL, &ts));
82  delete params[i];
83  }
84  }
85 
86 private:
87  WaitCondition *cond;
88  const uint num_threads;
89 };
90 
91 void *
92 start_waiter_thread(void *args)
93 {
94  thread_params *params = (thread_params *)args;
95  params->cond->wait();
96  pthread_exit(NULL);
97 }
98 
99 void *
100 start_abstimed_waiter_thread(void *args)
101 {
102  thread_params * params = (thread_params *)args;
103  struct timespec ts;
104  EXPECT_NE(-1, clock_gettime(CLOCK_REALTIME, &ts));
105  ts.tv_sec += 5;
106  params->cond->abstimed_wait(ts.tv_sec, 0);
107  pthread_exit(NULL);
108 }
109 
110 void *
111 start_reltimed_waiter_thread(void *args)
112 {
113  thread_params *params = (thread_params *)args;
114  params->cond->reltimed_wait(10, 0);
115  pthread_exit(NULL);
116 }
117 
118 TEST_F(WaitConditionTest, CancelWaitingThread)
119 {
120  start_test(start_waiter_thread);
121 }
122 
123 TEST_F(WaitConditionTest, CancelAbsTimedWaitingThread)
124 {
125  start_test(start_abstimed_waiter_thread);
126 }
127 
128 TEST_F(WaitConditionTest, CancelRelTimedWaitingThread)
129 {
130  start_test(start_reltimed_waiter_thread);
131 }
fawkes::WaitCondition
Definition: wait_condition.h:42
thread_params
The parameters passed to the threads.
Definition: test_wait_condition.cpp:36
fawkes::WaitCondition::wait
void wait()
Wait for the condition forever.
Definition: wait_condition.cpp:145
thread_params::cond
WaitCondition * cond
The thread's wait condition.
Definition: test_wait_condition.cpp:39
fawkes::WaitCondition::abstimed_wait
bool abstimed_wait(long int sec, long int nanosec)
Wait with absolute timeout.
Definition: wait_condition.cpp:175
WaitConditionTest::start_test
void start_test(void *(*thread_func)(void *))
Start threads with the given function, cancel the threads and assert they have terminated.
Definition: test_wait_condition.cpp:63
fawkes
fawkes::WaitCondition::reltimed_wait
bool reltimed_wait(unsigned int sec, unsigned int nanosec)
Wait with relative timeout.
Definition: wait_condition.cpp:212
WaitConditionTest
Definition: test_wait_condition.cpp:47