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 #include <unistd.h>
26 #include <time.h>
27 
28 #include <core/threading/wait_condition.h>
29 
30 using namespace fawkes;
31 
32 /** The parameters passed to the threads. */
34 {
35  /** The thread's wait condition. */
37 };
38 
39 /** @class WaitConditionTest
40  * Test class for WaitConditions
41  * This class tets basic functionality of WaitConditions,
42  * mainly thread cancellation problems
43  */
44 class WaitConditionTest : public ::testing::Test
45 {
46 protected:
48  : cond(new WaitCondition()),
49  num_threads(2)
50  {
51  }
52  virtual ~WaitConditionTest() {
53  delete cond;
54  }
55 
56  /** Start threads with the given function, cancel the threads
57  * and assert they have terminated.
58  * @param thread_func The function the threads are started with.
59  */
60  void start_test(void * (*thread_func) (void *)) {
61  pthread_t threads[num_threads];
62  thread_params *params[num_threads];
63  for (uint i = 0; i < num_threads; i++) {
64  params[i] = new thread_params();
65  params[i]->cond = cond;
66  pthread_create(&threads[i], NULL, thread_func, params[i]);
67  pthread_yield();
68  }
69 
70  usleep(1000);
71  for (uint i = 0; i < num_threads; i++) {
72  pthread_cancel(threads[i]);
73  struct timespec ts;
74  ASSERT_NE(-1, clock_gettime(CLOCK_REALTIME, &ts));
75  // give the thread two seconds to terminate
76  ts.tv_sec += 2;
77  ASSERT_EQ(0, pthread_timedjoin_np(threads[i], NULL, &ts));
78  delete params[i];
79  }
80  }
81 
82 private:
83  WaitCondition *cond;
84  const uint num_threads;
85 };
86 
87 
88 void * start_waiter_thread(void * args)
89 {
90  thread_params *params = (thread_params *) args;
91  params->cond->wait();
92  pthread_exit(NULL);
93 }
94 
95 void * start_abstimed_waiter_thread(void * args)
96 {
97  thread_params *params = (thread_params *) args;
98  struct timespec ts;
99  EXPECT_NE(-1, clock_gettime(CLOCK_REALTIME, &ts));
100  ts.tv_sec += 5;
101  params->cond->abstimed_wait(ts.tv_sec, 0);
102  pthread_exit(NULL);
103 }
104 
105 void * start_reltimed_waiter_thread(void * args)
106 {
107  thread_params *params = (thread_params *) args;
108  params->cond->reltimed_wait(10, 0);
109  pthread_exit(NULL);
110 }
111 
112 TEST_F(WaitConditionTest, CancelWaitingThread)
113 {
114  start_test(start_waiter_thread);
115 }
116 
117 TEST_F(WaitConditionTest, CancelAbsTimedWaitingThread)
118 {
119  start_test(start_abstimed_waiter_thread);
120 }
121 
122 TEST_F(WaitConditionTest, CancelRelTimedWaitingThread)
123 {
124  start_test(start_reltimed_waiter_thread);
125 }
126 
Test class for WaitConditions This class tets basic functionality of WaitConditions, mainly thread cancellation problems.
Wait until a given condition holds.
bool reltimed_wait(unsigned int sec, unsigned int nanosec)
Wait with relative timeout.
Fawkes library namespace.
WaitCondition * cond
The thread&#39;s wait condition.
The parameters passed to the threads.
void start_test(void *(*thread_func)(void *))
Start threads with the given function, cancel the threads and assert they have terminated.
void wait()
Wait for the condition forever.
bool abstimed_wait(long int sec, long int nanosec)
Wait with absolute timeout.