1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
|
//=============================================================================
/**
* @file Recursive_Condition_Bug_Test.cpp
*
* $Id: Recursive_Condition_Bug_Test.cpp 93638 2011-03-24 13:16:05Z johnnyw $
*
* This test program validates the functionality of the
* ACE_Condition<ACE_Recursive_Thread_Mutex> template
* specialization when combined with the
* ACE_Thread_Timer_Queue_Adapter on Win32 and Posix pthreads.
* It was added to test for bugs with the ACE_OS recursive
* condition implementation.
*
*
* @author Leonid Kvetnyi <leonidk@nice.com> and Douglas C. Schmidt <schmidt@cs.wustl.edu>
*/
//=============================================================================
#include "test_config.h"
#include "ace/OS_NS_sys_time.h"
#include "ace/Task_T.h"
#include "ace/Activation_Queue.h"
#include "ace/Timer_Heap.h"
#include "ace/Timer_Queue_Adapters.h"
#include "ace/Condition_Recursive_Thread_Mutex.h"
#if defined (ACE_HAS_THREADS)
// Number of iterations for the performance tests.
static int max_iterations = 30;
typedef ACE_Thread_Timer_Queue_Adapter<ACE_Timer_Heap> Thread_Timer_Queue;
class Test_Handler;
class Test_Task : public ACE_Task<ACE_MT_SYNCH>
{
public:
virtual int svc (void)
{
while (--max_iterations > 0)
{
// dequeue the next object
ACE_Message_Block * mb = 0;
if (this->getq (mb) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("(%t) %p\n"),
ACE_TEXT ("getq failed")),
-1);
Test_Handler *handler = reinterpret_cast<Test_Handler *> (mb->base ());
mb->release ();
ACE_Time_Value timeout = ACE_OS::gettimeofday () + ACE_Time_Value (1, 0);
if (timer_queue_.schedule (reinterpret_cast<ACE_Event_Handler *> (handler),
this,
timeout) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("(%t) %p\n"),
ACE_TEXT ("schedule failed")),
-1);
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("(%t) %d iteration(s) remain\n"),
max_iterations));
}
timer_queue_.deactivate ();
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("(%t) leaving the Test_task\n")));
return 0;
}
//FUZZ: disable check_for_lack_ACE_OS
virtual int open (void * = 0)
{
//FUZZ: enable check_for_lack_ACE_OS
if (ACE_Task<ACE_MT_SYNCH>::activate (THR_NEW_LWP, 1) != 0)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("(%t) %p\n"),
ACE_TEXT ("Test_Task::activate")),
-1);
if (0 != timer_queue_.activate ())
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("(%t) %p\n"),
ACE_TEXT ("Test_Task::queue activate")),
-1);
return 0;
}
private:
Thread_Timer_Queue timer_queue_;
};
class Test_Handler : public ACE_Event_Handler
{
public:
virtual int handle_timeout (const ACE_Time_Value &,
const void *arg)
{
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%t) Test_Handler::handle_timeout\n")));
void *nc_arg = const_cast<void *> (arg);
Test_Task *test_task =
reinterpret_cast<Test_Task *> (nc_arg);
ACE_Message_Block *mb = 0;
ACE_NEW_MALLOC_RETURN (mb,
static_cast<ACE_Message_Block *> (ACE_Allocator::instance()->malloc (sizeof (ACE_Message_Block))),
ACE_Message_Block (sizeof (*this), // size
ACE_Message_Block::MB_DATA, // type
0, // cont
(char *) this, // data
0,
0,
ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY,
ACE_Time_Value::zero,
ACE_Time_Value::max_time,
0,
ACE_Allocator::instance()), // data
-1);
test_task->putq (mb);
return 0;
}
};
#endif /* ACE_HAS_THREADS */
int
run_main (int, ACE_TCHAR *[])
{
ACE_START_TEST (ACE_TEXT ("Recursive_Condition_Bug_Test"));
#if defined (ACE_HAS_THREADS)
// Timer queue usage.
Test_Handler handler;
Test_Task task;
if (0 != task.open ())
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("(%t) %p\n"),
ACE_TEXT ("open")),
-1);
ACE_Message_Block *mb = 0;
ACE_NEW_MALLOC_RETURN (mb,
static_cast<ACE_Message_Block *> (ACE_Allocator::instance()->malloc (sizeof (ACE_Message_Block))),
ACE_Message_Block (sizeof (handler), // size
ACE_Message_Block::MB_DATA, // type
0, // cont
(char *) &handler,
0,
0,
ACE_DEFAULT_MESSAGE_BLOCK_PRIORITY,
ACE_Time_Value::zero,
ACE_Time_Value::max_time,
0,
ACE_Allocator::instance()), // data
-1);
if (-1 == task.putq (mb))
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("(%t) %p\n"),
ACE_TEXT ("putq")),
-1);
if (ACE_Thread_Manager::instance ()->wait () == -1)
ACE_ERROR_RETURN ((LM_ERROR,
"wait on Thread_Manager failed"),
-1);
#else
ACE_ERROR ((LM_ERROR,
ACE_TEXT ("ACE doesn't support recursive condition variables on this platform\n")));
#endif /* ACE_HAS_THREADS */
ACE_END_TEST;
return 0;
}
|