2 * @file Bug_2609_Regression_Test.cpp
4 * Reproduces the problems reported in bug 2609:
5 * http://bugzilla.dre.vanderbilt.edu/show_bug.cgi?id=2609
7 * @author Milan Cvetkovic <milan.cvetkovic@mpathix.com>
10 #include "test_config.h"
11 #include "ace/Svc_Handler.h"
12 #include "ace/Acceptor.h"
13 #include "ace/SOCK_Stream.h"
14 #include "ace/SOCK_Acceptor.h"
15 #include "ace/INET_Addr.h"
16 #include "ace/Trace.h"
17 #include "ace/SOCK_Connector.h"
18 #include "ace/Thread_Semaphore.h"
20 #if defined (ACE_HAS_THREADS) && !defined ACE_LACKS_ACCEPT
22 # define TEST_TRACE(X) ACE_Trace ____ (ACE_TEXT (X), __LINE__, ACE_TEXT (__FILE__))
24 bool g_handler_deleted
= false;
25 // use semaphore for synchronization
27 ACE_Thread_Semaphore
g_semaphore (0);
29 class My_Svc_Handler
: public ACE_Svc_Handler
<ACE_SOCK_STREAM
,ACE_NULL_SYNCH
>
32 using super
= ACE_Svc_Handler
<ACE_SOCK_Stream
, ACE_NULL_SYNCH
>;
35 TEST_TRACE ("My_Svc_Handler:My_Svc_Handler");
36 g_handler_deleted
= false;
37 reference_counting_policy().value(
38 Reference_Counting_Policy::ENABLED
);
41 ~My_Svc_Handler() override
43 TEST_TRACE ("My_Svc_Handler::~My_Svc_Handler");
44 g_handler_deleted
= true;
47 //FUZZ: disable check_for_lack_ACE_OS
48 int open (void* pv
) override
51 g_semaphore
.release (); // signal open completed
52 // super::open() will register_handler for input. The default
53 // handle_input() from ACE_Event_Handler will return -1, triggering
54 // handler removal from the reactor.
55 return super::open (pv
);
57 //FUZZ: enable check_for_lack_ACE_OS
59 int handle_close (ACE_HANDLE
, ACE_Reactor_Mask
) override
61 TEST_TRACE ("handle_close");
62 if (g_handler_deleted
)
65 ACE_TEXT ("Handler deleted in base handle_close()\n")));
67 // signal handle_close() completed
68 g_semaphore
.release ();
73 struct My_Task
: public ACE_Task_Base
77 TEST_TRACE ("My_Task::svc");
78 ACE_Reactor
*r
= ACE_Reactor::instance ();
79 r
->owner (ACE_OS::thr_self ());
80 int rv
= r
->run_reactor_event_loop ();
84 ACE_TEXT ("Cannot run %p\n"),
85 ACE_TEXT ("reactor event loop")));
91 // event handler used to signal when the reactor started
92 struct Timer_Handler
: public ACE_Event_Handler
94 int handle_timeout (const ACE_Time_Value
&, const void*) override
96 g_semaphore
.release (); // signal reactor started
101 using My_Acceptor
= ACE_Acceptor
<My_Svc_Handler
, ACE_SOCK_Acceptor
>;
106 run_main (int, ACE_TCHAR
*[])
108 ACE_START_TEST (ACE_TEXT ("Bug_2609_Regression_Test"));
112 #if defined (ACE_HAS_THREADS) && !defined ACE_LACKS_ACCEPT
114 My_Acceptor acceptor
;
115 if (-1 == acceptor
.open (ACE_sap_any_cast (const ACE_INET_Addr
&)))
116 ACE_ERROR_RETURN ((LM_ERROR
,
118 ACE_TEXT ("acceptor open")),
120 ACE_INET_Addr listen_addr
;
121 acceptor
.acceptor ().get_local_addr (listen_addr
);
122 #if defined (ACE_HAS_IPV6)
123 const ACE_TCHAR
*me
=
124 listen_addr
.get_type () == PF_INET
? ACE_LOCALHOST
: ACE_IPV6_LOCALHOST
;
126 const ACE_TCHAR
*me
= ACE_LOCALHOST
;
127 #endif /* ACE_HAS_IPV6 */
128 ACE_INET_Addr
connect_addr (listen_addr
.get_port_number (),
130 listen_addr
.get_type ());
132 Timer_Handler timer_handler
;
133 ACE_Reactor::instance()->schedule_timer (&timer_handler
,
138 int activated
= task
.activate ();
141 ACE_ERROR_RETURN ((LM_ERROR
,
143 ACE_TEXT ("Error activating task")),
147 g_semaphore
.acquire (); // wait for reactor to start
149 ACE_SOCK_Connector c1
;
151 if (-1 == c1
.connect (s1
, connect_addr
))
153 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("%p\n"), ACE_TEXT("connect")));
158 g_semaphore
.acquire (); // wait for open to complete
159 s1
.close (); // will trip handle_input()
160 g_semaphore
.acquire (); // wait for handle_close to complete
163 ACE_Reactor::instance ()->end_reactor_event_loop ();
167 ACE_TEXT ("threads/accept not supported on this platform\n")));