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
|
//=============================================================================
/**
* @file test_end_event_loop.cpp
*
* $Id: test_end_event_loop.cpp 93639 2011-03-24 13:32:13Z johnnyw $
*
* This program tests the event loop mechanism of the
* Proactor. To end the event loop, threads that are blocked in
* waiting for completions are woken up and the event loop comes
* to the end. This is tested in this program.
* Threads are doing <run_event_loop> with/without time_out
* values and the main thread calls <end_event_loop>.
* make
* ./test_end_event_loop
*
* @author Alexander Babu Arulanthu <alex@cs.wustl.edu>
*/
//=============================================================================
#include "ace/OS_NS_unistd.h"
#include "ace/Proactor.h"
#include "ace/Task.h"
#include "ace/WIN32_Proactor.h"
#include "ace/POSIX_Proactor.h"
#include "ace/OS_main.h"
#if defined (ACE_HAS_WIN32_OVERLAPPED_IO) || defined (ACE_HAS_AIO_CALLS)
// This only works on Win32 platforms and on Unix platforms supporting
// POSIX aio calls.
/**
* @class My_Task:
*
* @brief Contains thread functions which execute event loops. Each
* thread waits for a different signal.
*/
class My_Task: public ACE_Task <ACE_NULL_SYNCH>
{
public:
// Constructor.
My_Task (void)
: time_flag_ (0)
{}
/// Destructor.
virtual ~My_Task (void) {}
//FUZZ: disable check_for_lack_ACE_OS
// If time_flag is zero do the eventloop indefinitely, otherwise do
// it for finite amount of time (13secs!!!).
int open (void *timed_event_loop)
{
//FUZZ: enble check_for_lack_ACE_OS
// Set the local variable.
if (timed_event_loop == 0)
this->time_flag_ = 0;
else
this->time_flag_ = 1;
// Spawn the threads.
if (this->activate (THR_NEW_LWP, 5) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
"%N:%l:%p\n",
"My_Task:open: <activate> failed"),
-1);
return 0;
}
// Thread function.
int svc (void)
{
ACE_DEBUG ((LM_DEBUG,
"(%P|%t):Starting svc routine\n"));
if (this->time_flag_)
{
ACE_DEBUG ((LM_DEBUG,
"(%P|%t):Going to do *timed* <run_event_loop>\n"));
ACE_Time_Value run_time (13);
if (ACE_Proactor::instance ()->run_event_loop (run_time) == -1)
ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t):%p.\n",
"<Proactor::run_event_loop> failed"),
-1);
}
else
{
ACE_DEBUG ((LM_DEBUG,
"(%P|%t):Going to do *indefinite* <run_event_loop>\n"));
if (ACE_Proactor::instance ()->run_event_loop () == -1)
ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t):%p.\n",
"<Proactor::run_event_loop> failed"),
-1);
}
return 0;
};
private:
/// If zero, indefinite event loop, otherwise timed event loop.
int time_flag_;
};
int
ACE_TMAIN (int argc, ACE_TCHAR *argv [])
{
ACE_UNUSED_ARG (argc);
ACE_UNUSED_ARG (argv);
ACE_DEBUG ((LM_DEBUG,
"(%P | %t):Test starts\n"));
// Let us get the singleton proactor created here. This is very
// important. This will mask the signal used in the Proactor masked
// for the main thread (and all the threads).
ACE_Proactor *proactor = ACE_Proactor::instance ();
ACE_UNUSED_ARG (proactor);
My_Task task1, task2;
// Test the indefinite run event loop.
if (task1.open (0) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
"%N:%l:(%P | %t):Failed to <open> the task\n"),
1);
// Test the indefinite run event loop. Just pass a non-zero.
if (task2.open ((void *)&task2) == -1)
ACE_ERROR_RETURN ((LM_ERROR,
"%N:%l:(%P | %t):Failed to <open> the task\n"),
1);
// Give a gap.
ACE_OS::sleep (3);
// End the event loop.
if (ACE_Proactor::instance ()->end_event_loop () == -1)
ACE_ERROR_RETURN ((LM_ERROR,
"%N:%l:(%P | %t):Failed to <end_event_loop>\n"),
1);
ACE_Thread_Manager::instance ()->wait ();
ACE_DEBUG ((LM_DEBUG,
"(%P | %t):Test ends\n"));
return 0;
}
#else /* ACE_HAS_WIN32_OVERLAPPED_IO || ACE_HAS_AIO_CALLS */
int
ACE_TMAIN (int, ACE_TCHAR *[])
{
ACE_DEBUG ((LM_DEBUG,
"This example cannot work with AIOCB_Proactor.\n"));
return 1;
}
#endif /* ACE_HAS_WIN32_OVERLAPPED_IO || ACE_HAS_AIO_CALLS */
|