2 * @file Bug_2610_Regression_Test.cpp
4 * Reproduces the problems reported in bug 2610:
5 * http://bugzilla.dre.vanderbilt.edu/show_bug.cgi?id=2610
7 * @author Milan Cvetkovic <milan.cvetkovic@mpathix.com>
10 #include "test_config.h"
11 #include "ace/INET_Addr.h"
12 #include "ace/SOCK_Stream.h"
13 #include "ace/SOCK_Acceptor.h"
14 #include "ace/SOCK_Connector.h"
15 #include "ace/Svc_Handler.h"
16 #include "ace/Acceptor.h"
17 #include "ace/Connector.h"
18 #include "ace/Trace.h"
19 #include "ace/Thread_Semaphore.h"
21 #if defined (ACE_HAS_THREADS)
23 # define TEST_TRACE(X) ACE_Trace ____ (ACE_TEXT (X), __LINE__, ACE_TEXT (__FILE__))
25 int g_svc_handlers_leaked
= 0;
26 // use semaphore for synchronization
28 ACE_Thread_Semaphore
g_semaphore (0);
30 class My_Svc_Handler
: public ACE_Svc_Handler
<ACE_SOCK_STREAM
,ACE_NULL_SYNCH
>
33 typedef ACE_Svc_Handler
<ACE_SOCK_STREAM
,ACE_NULL_SYNCH
> super
;
36 TEST_TRACE ("My_Svc_Handler:My_Svc_Handler");
37 ++g_svc_handlers_leaked
;
38 reference_counting_policy().value(
39 Reference_Counting_Policy::ENABLED
);
44 TEST_TRACE ("My_Svc_Handler::~My_Svc_Handler");
45 --g_svc_handlers_leaked
;
48 int handle_close (ACE_HANDLE
/*fd*/, ACE_Reactor_Mask
/*mask*/)
50 TEST_TRACE ("handle_close");
51 g_semaphore
.release();
56 bool g_acceptor_accept_fails
;
58 class My_Acceptor
: public ACE_Acceptor
<My_Svc_Handler
, ACE_SOCK_ACCEPTOR
>
61 typedef ACE_Acceptor
<My_Svc_Handler
, ACE_SOCK_ACCEPTOR
> super
;
62 My_Acceptor () : super (ACE_INET_Addr(9000)) {}
65 int accept_svc_handler (My_Svc_Handler
*svc_handler
)
67 TEST_TRACE ("accept_svc_handler");
68 int rv
= super::accept_svc_handler(svc_handler
);
69 if (g_acceptor_accept_fails
)
71 g_semaphore
.release();
76 int activate_svc_handler (My_Svc_Handler
* /*svc_handler*/)
78 TEST_TRACE ("My_Acceptor::activate_svc_handler");
79 g_semaphore
.release();
84 class My_Connector
: public ACE_Connector
<My_Svc_Handler
, ACE_SOCK_CONNECTOR
>
87 typedef ACE_Connector
<My_Svc_Handler
, ACE_SOCK_CONNECTOR
> super
;
89 int activate_svc_handler (My_Svc_Handler
* /*svc_handler*/)
91 TEST_TRACE ("My_Connector::activate_svc_handler");
92 g_semaphore
.release();
97 struct My_Task
: public ACE_Task_Base
101 TEST_TRACE ("My_Task::svc");
102 ACE_Reactor::instance()->owner(ACE_OS::thr_self());
103 int rv
= ACE_Reactor::instance()->run_reactor_event_loop();
106 ACE_ERROR ((LM_ERROR
,
108 ACE_TEXT ("Cannot run reactor event loop")));
114 // event handler used to signal when the reactor started
115 struct Timer_Handler
: public ACE_Event_Handler
117 int handle_timeout (const ACE_Time_Value
&, const void*)
119 g_semaphore
.release(); // signal reactor started
127 run_main (int, ACE_TCHAR
*[])
129 ACE_START_TEST (ACE_TEXT ("Bug_2610_Regression_Test"));
131 #if defined (ACE_HAS_THREADS)
133 My_Acceptor acceptor
;
134 Timer_Handler timer_handler
;
135 ACE_Reactor::instance()->schedule_timer(
136 &timer_handler
, 0, ACE_Time_Value(0));
139 int activated
= task
.activate();
142 ACE_ERROR_RETURN ((LM_ERROR
,
144 ACE_TEXT ("Could not activate task")),
148 // Don't assume addr family of the listener - check and adapt when needed.
149 ACE_INET_Addr listen_addr
;
150 acceptor
.acceptor ().get_local_addr (listen_addr
);
151 #if defined (ACE_HAS_IPV6)
152 const ACE_TCHAR
*me
=
153 listen_addr
.get_type () == PF_INET
? ACE_LOCALHOST
: ACE_IPV6_LOCALHOST
;
155 const ACE_TCHAR
*me
= ACE_LOCALHOST
;
156 #endif /* ACE_HAS_IPV6 */
157 ACE_INET_Addr
a1 (listen_addr
.get_port_number (),
159 listen_addr
.get_type ());
160 ACE_SOCK_Connector c1
;
161 g_semaphore
.acquire();// wait for reactor to start
164 g_acceptor_accept_fails
= true;
166 if (-1 == c1
.connect (s1
, a1
))
168 ACE_ERROR_RETURN ((LM_ERROR
,
170 ACE_TEXT ("Could not connect")),
173 g_semaphore
.acquire(); // wait for accept_svc_handler() to start
176 g_acceptor_accept_fails
= false;
178 if (-1 == c1
.connect (s1
, a1
))
180 ACE_ERROR_RETURN ((LM_ERROR
,
182 ACE_TEXT ("Could not connect")),
185 g_semaphore
.acquire(); // wait for activate_svc_handler to complete
189 My_Svc_Handler
* handler
=0;
190 My_Connector connector
;
191 connector
.connect (handler
, a1
);
192 ACE_Event_Handler_var
safe_handler (handler
);
193 g_semaphore
.acquire(); // wait for connect to complete
195 ACE_Reactor::end_event_loop();
198 if (g_svc_handlers_leaked
!= 0)
200 ACE_ERROR_RETURN ((LM_ERROR
,
201 ACE_TEXT ("Svc_Handler leakage detected, ")
202 ACE_TEXT ("%d objects remain\n"),
203 g_svc_handlers_leaked
),
208 ACE_TEXT ("threads not supported on this platform\n")));