1 #include "ace/OS_NS_sys_time.h"
2 #include "ace/os_include/os_netdb.h"
5 #include "ace/Log_Msg.h"
6 #include "ace/INET_Addr.h"
7 #include "ace/SOCK_Acceptor.h"
8 #include "ace/Reactor.h"
11 class ClientAcceptor
: public ACE_Event_Handler
14 virtual ~ClientAcceptor ();
16 //FUZZ: disable check_for_lack_ACE_OS
17 int open (const ACE_INET_Addr
&listen_addr
);
18 //FUZZ: enable check_for_lack_ACE_OS
20 // Get this handler's I/O handle.
21 virtual ACE_HANDLE
get_handle () const
22 { return this->acceptor_
.get_handle (); }
24 // Called when a connection is ready to accept.
25 virtual int handle_input (ACE_HANDLE fd
= ACE_INVALID_HANDLE
);
27 // Called when this handler is removed from the ACE_Reactor.
28 virtual int handle_close (ACE_HANDLE handle
,
29 ACE_Reactor_Mask close_mask
);
32 ACE_SOCK_Acceptor acceptor_
;
36 // Listing 6 code/ch07
37 #include "ace/Message_Block.h"
38 #include "ace/Message_Queue.h"
39 #include "ace/SOCK_Stream.h"
40 #include "ace/Synch.h"
42 class ClientService
: public ACE_Event_Handler
45 ACE_SOCK_Stream
&peer () { return this->sock_
; }
47 //FUZZ: disable check_for_lack_ACE_OS
49 //FUZZ: enable check_for_lack_ACE_OS
51 // Get this handler's I/O handle.
52 virtual ACE_HANDLE
get_handle () const
53 { return this->sock_
.get_handle (); }
55 // Called when input is available from the client.
56 virtual int handle_input (ACE_HANDLE fd
= ACE_INVALID_HANDLE
);
58 // Called when output is possible.
59 virtual int handle_output (ACE_HANDLE fd
= ACE_INVALID_HANDLE
);
61 // Called when this handler is removed from the ACE_Reactor.
62 virtual int handle_close (ACE_HANDLE handle
,
63 ACE_Reactor_Mask close_mask
);
66 ACE_SOCK_Stream sock_
;
67 ACE_Message_Queue
<ACE_NULL_SYNCH
> output_queue_
;
71 // Listing 5 code/ch07
72 ClientAcceptor::~ClientAcceptor ()
74 this->handle_close (ACE_INVALID_HANDLE
, 0);
78 // Listing 2 code/ch07
80 ClientAcceptor::open (const ACE_INET_Addr
&listen_addr
)
82 if (this->acceptor_
.open (listen_addr
, 1) == -1)
83 ACE_ERROR_RETURN ((LM_ERROR
,
85 ACE_TEXT ("acceptor.open")),
87 return this->reactor ()->register_handler
88 (this, ACE_Event_Handler::ACCEPT_MASK
);
92 // Listing 3 code/ch07
94 ClientAcceptor::handle_input (ACE_HANDLE
)
96 ClientService
*client
= 0;
97 ACE_NEW_RETURN (client
, ClientService
, -1);
98 std::unique_ptr
<ClientService
> p (client
);
100 if (this->acceptor_
.accept (client
->peer ()) == -1)
101 ACE_ERROR_RETURN ((LM_ERROR
,
102 ACE_TEXT ("(%P|%t) %p\n"),
103 ACE_TEXT ("Failed to accept ")
104 ACE_TEXT ("client connection")),
107 client
->reactor (this->reactor ());
108 if (client
->open () == -1)
109 client
->handle_close (ACE_INVALID_HANDLE
, 0);
114 // Listing 4 code/ch07
116 ClientAcceptor::handle_close (ACE_HANDLE
, ACE_Reactor_Mask
)
118 if (this->acceptor_
.get_handle () != ACE_INVALID_HANDLE
)
120 ACE_Reactor_Mask m
= ACE_Event_Handler::ACCEPT_MASK
|
121 ACE_Event_Handler::DONT_CALL
;
122 this->reactor ()->remove_handler (this, m
);
123 this->acceptor_
.close ();
129 // Listing 7 code/ch07
131 ClientService::open ()
133 ACE_TCHAR peer_name
[MAXHOSTNAMELEN
];
134 ACE_INET_Addr peer_addr
;
135 if (this->sock_
.get_remote_addr (peer_addr
) == 0 &&
136 peer_addr
.addr_to_string (peer_name
, MAXHOSTNAMELEN
) == 0)
137 ACE_DEBUG ((LM_DEBUG
,
138 ACE_TEXT ("(%P|%t) Connection from %s\n"),
140 return this->reactor ()->register_handler
141 (this, ACE_Event_Handler::READ_MASK
);
145 // Listing 8 code/ch07
147 ClientService::handle_input (ACE_HANDLE
)
149 const size_t INPUT_SIZE
= 4096;
150 char buffer
[INPUT_SIZE
];
151 ssize_t recv_cnt
, send_cnt
;
153 if ((recv_cnt
= this->sock_
.recv (buffer
, sizeof(buffer
))) <= 0)
155 ACE_DEBUG ((LM_DEBUG
,
156 ACE_TEXT ("(%P|%t) Connection closed\n")));
161 this->sock_
.send (buffer
, static_cast<size_t> (recv_cnt
));
162 if (send_cnt
== recv_cnt
)
164 if (send_cnt
== -1 && ACE_OS::last_error () != EWOULDBLOCK
)
165 ACE_ERROR_RETURN ((LM_ERROR
,
166 ACE_TEXT ("(%P|%t) %p\n"),
171 ACE_Message_Block
*mb
= 0;
173 static_cast<size_t> ((recv_cnt
- send_cnt
));
174 ACE_NEW_RETURN (mb
, ACE_Message_Block (remaining
), -1);
175 mb
->copy (&buffer
[send_cnt
], remaining
);
176 int output_off
= this->output_queue_
.is_empty ();
177 ACE_Time_Value
nowait (ACE_OS::gettimeofday ());
178 if (this->output_queue_
.enqueue_tail (mb
, &nowait
) == -1)
180 ACE_ERROR ((LM_ERROR
,
181 ACE_TEXT ("(%P|%t) %p; discarding data\n"),
182 ACE_TEXT ("enqueue failed")));
187 return this->reactor ()->register_handler
188 (this, ACE_Event_Handler::WRITE_MASK
);
193 // Listing 9 code/ch07
195 ClientService::handle_output (ACE_HANDLE
)
197 ACE_Message_Block
*mb
= 0;
198 ACE_Time_Value
nowait (ACE_OS::gettimeofday ());
199 while (0 <= this->output_queue_
.dequeue_head
203 this->sock_
.send (mb
->rd_ptr (), mb
->length ());
205 ACE_ERROR ((LM_ERROR
,
206 ACE_TEXT ("(%P|%t) %p\n"),
209 mb
->rd_ptr (static_cast<size_t> (send_cnt
));
210 if (mb
->length () > 0)
212 this->output_queue_
.enqueue_head (mb
);
217 return (this->output_queue_
.is_empty ()) ? -1 : 0;
221 // Listing 10 code/ch07
223 ClientService::handle_close (ACE_HANDLE
, ACE_Reactor_Mask mask
)
225 if (mask
== ACE_Event_Handler::WRITE_MASK
)
227 mask
= ACE_Event_Handler::ALL_EVENTS_MASK
|
228 ACE_Event_Handler::DONT_CALL
;
229 this->reactor ()->remove_handler (this, mask
);
230 this->sock_
.close ();
231 this->output_queue_
.flush ();
237 // Listing 12 code/ch07
238 class LoopStopper
: public ACE_Event_Handler
241 LoopStopper (int signum
= SIGINT
);
243 // Called when object is signaled by OS.
244 virtual int handle_signal (int signum
, siginfo_t
* = 0, ucontext_t
* = 0);
247 LoopStopper::LoopStopper (int signum
)
249 ACE_Reactor::instance ()->register_handler (signum
, this);
253 LoopStopper::handle_signal (int, siginfo_t
*, ucontext_t
*)
255 ACE_Reactor::instance ()->end_reactor_event_loop ();
260 // Listing 13 code/ch07
261 #include "ace/Signal.h"
263 class LogSwitcher
: public ACE_Event_Handler
266 LogSwitcher (int on_sig
, int off_sig
);
268 // Called when object is signaled by OS.
269 virtual int handle_signal (int signum
, siginfo_t
* = 0, ucontext_t
* = 0);
271 // Called when an exceptional event occurs.
272 virtual int handle_exception (ACE_HANDLE fd
= ACE_INVALID_HANDLE
);
277 int on_sig_
; // Signal to turn logging on
278 int off_sig_
; // Signal to turn logging off
279 int on_off_
; // 1 == turn on, 0 == turn off
282 LogSwitcher::LogSwitcher (int on_sig
, int off_sig
)
283 : on_sig_ (on_sig
), off_sig_ (off_sig
)
286 sigs
.sig_add (on_sig
);
287 sigs
.sig_add (off_sig
);
288 ACE_Reactor::instance ()->register_handler (sigs
, this);
292 // Listing 14 code/ch07
294 LogSwitcher::handle_signal (int signum
, siginfo_t
*, ucontext_t
*)
296 if (signum
== this->on_sig_
|| signum
== this->off_sig_
)
298 this->on_off_
= signum
== this->on_sig_
;
299 ACE_Reactor::instance ()->notify (this);
305 // Listing 15 code/ch07
307 LogSwitcher::handle_exception (ACE_HANDLE
)
310 ACE_LOG_MSG
->clr_flags (ACE_Log_Msg::SILENT
);
312 ACE_LOG_MSG
->set_flags (ACE_Log_Msg::SILENT
);
317 // Listing 11 code/ch07
318 int ACE_TMAIN (int, ACE_TCHAR
*[])
320 ACE_INET_Addr
port_to_listen ("HAStatus");
321 ClientAcceptor acceptor
;
322 acceptor
.reactor (ACE_Reactor::instance ());
323 if (acceptor
.open (port_to_listen
) == -1)
326 ACE_Reactor::instance ()->run_reactor_event_loop ();