1 // Perform a torture test of multiple ACE_Reactors and ACE_Tasks in
2 // the same process... Thanks to Detlef Becker for contributing this.
4 #include "ace/Reactor.h"
5 #include "ace/Service_Config.h"
7 #include "ace/Atomic_Op.h"
10 #if defined (ACE_HAS_THREADS)
12 #include "ace/Recursive_Thread_Mutex.h"
14 static const int NUM_INVOCATIONS
= 10;
15 static const int MAX_TASKS
= 20;
17 class Test_Task
: public ACE_Task
<ACE_MT_SYNCH
>
23 //FUZZ: disable check_for_lack_ACE_OS
24 virtual int open (void *args
= 0);
25 virtual int close (u_long flags
= 0);
26 //FUZZ: enable check_for_lack_ACE_OS
30 virtual int handle_input (ACE_HANDLE handle
);
31 virtual int handle_close (ACE_HANDLE fd
,
32 ACE_Reactor_Mask close_mask
);
37 static int task_count_
;
40 int Test_Task::task_count_
= 0;
42 static ACE_Atomic_Op
<ACE_Thread_Mutex
, int> done_count
= MAX_TASKS
* 2;
44 static ACE_Recursive_Thread_Mutex reclock_
;
46 Test_Task::Test_Task ()
49 ACE_GUARD (ACE_Recursive_Thread_Mutex
, ace_mon
, reclock_
);
51 Test_Task::task_count_
++;
53 "(%t) TT+ Test_Task::task_count_ = %d\n",
54 Test_Task::task_count_
));
57 Test_Task::~Test_Task ()
59 ACE_GUARD (ACE_Recursive_Thread_Mutex
, ace_mon
, reclock_
);
62 "(%t) TT- Test_Task::task_count_ = %d\n",
63 Test_Task::task_count_
));
67 Test_Task::open (void *args
)
69 this->reactor ((ACE_Reactor
*) args
);
70 return this->activate (THR_NEW_LWP
);
74 Test_Task::close (u_long
)
76 ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex
, ace_mon
, reclock_
, -1);
78 Test_Task::task_count_
--;
80 "(%t) close Test_Task::task_count_ = %d\n",
81 Test_Task::task_count_
));
88 for (int i
= 0; i
< NUM_INVOCATIONS
; i
++)
92 // ACE_DEBUG ((LM_DEBUG, "(%t) calling notify %d\n", i));
94 if (this->reactor ()->notify (this, ACE_Event_Handler::READ_MASK
) == -1)
95 ACE_ERROR_RETURN ((LM_ERROR
, "(%t) %p\n", "notify"), -1);
97 // ACE_DEBUG ((LM_DEBUG, "(%t) leaving notify %d\n", i));
104 Test_Task::handle_close (ACE_HANDLE
,
107 ACE_DEBUG ((LM_DEBUG
, "(%t) handle_close\n"));
112 Test_Task::handle_input (ACE_HANDLE
)
114 ACE_DEBUG ((LM_DEBUG
, "(%t) handle_input\n"));
118 if (this->handled_
== NUM_INVOCATIONS
)
121 ACE_DEBUG ((LM_DEBUG
,
122 "(%t) handle_input, handled_ = %d, done_count = %d\n",
123 this->handled_
, done_count
.value ()));
126 ACE_OS::thr_yield ();
133 ACE_Reactor
*reactor
= (ACE_Reactor
*) args
;
135 reactor
->owner (ACE_Thread::self ());
137 ACE_Time_Value
timeout (4);
141 //ACE_DEBUG ((LM_DEBUG, "(%t) calling handle_events\n"));
143 switch (reactor
->handle_events (timeout
))
146 ACE_ERROR_RETURN ((LM_ERROR
, "(%t) %p\n", "reactor"), 0);
149 ACE_ERROR_RETURN ((LM_ERROR
, "(%t) timeout\n"), 0);
153 // ACE_DEBUG ((LM_DEBUG, "(%t) done with handle_events\n"));
156 ACE_NOTREACHED(return 0);
160 ACE_TMAIN (int, ACE_TCHAR
*[])
162 ACE_Reactor
*react1
= ACE_Reactor::instance ();
163 ACE_Reactor
*react2
= new ACE_Reactor ();
164 Test_Task tt1
[MAX_TASKS
];
165 Test_Task tt2
[MAX_TASKS
];
167 for (int i
= 0; i
< MAX_TASKS
; i
++)
169 tt1
[i
].open (react1
);
170 tt2
[i
].open (react2
);
173 if (ACE_Thread_Manager::instance ()->spawn
174 (ACE_THR_FUNC (worker
), (void *) react1
, THR_NEW_LWP
) == -1)
175 ACE_ERROR_RETURN ((LM_ERROR
, "%p\n", "spawn"), -1);
177 else if (ACE_Thread_Manager::instance ()->spawn
178 (ACE_THR_FUNC (worker
), (void *) react2
, THR_NEW_LWP
) == -1)
179 ACE_ERROR_RETURN ((LM_ERROR
, "%p\n", "spawn"), -1);
181 ACE_Thread_Manager::instance ()->wait ();
182 ACE_DEBUG ((LM_DEBUG
, "(%t) done\n"));
189 ACE_TMAIN (int, ACE_TCHAR
*[])
191 ACE_ERROR ((LM_ERROR
, "threads not supported on this platform\n"));
194 #endif /* ACE_HAS_THREADS */