Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / ACE / netsvcs / lib / TS_Server_Handler.cpp
blob5bc042dc4f68b6f57eb873b93a417a4a295ed86a
1 #include "ace/SString.h"
2 #include "ace/Containers.h"
3 #include "ace/Get_Opt.h"
4 #include "TS_Server_Handler.h"
5 #include "ace/OS_NS_time.h"
6 #include "ace/Signal.h"
8 int
9 ACE_TS_Server_Acceptor::parse_args (int argc, ACE_TCHAR *argv[])
11 ACE_TRACE ("ACE_TS_Server_Acceptor::parse_args");
13 int service_port = ACE_DEFAULT_SERVER_PORT;
15 ACE_LOG_MSG->open (ACE_TEXT ("Time Service"));
17 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("p:"), 0);
19 for (int c; (c = get_opt ()) != -1; )
21 switch (c)
23 case 'p':
24 service_port = ACE_OS::atoi (get_opt.opt_arg ());
25 break;
26 default:
27 ACE_ERROR_RETURN ((LM_ERROR,
28 ACE_TEXT ("%n:\n[-p server-port]\n"), 1),
29 -1);
32 this->service_addr_.set (service_port);
33 return 0;
36 int
37 ACE_TS_Server_Acceptor::init (int argc, ACE_TCHAR *argv[])
39 ACE_TRACE ("ACE_TS_Server_Acceptor::init");
41 // Use the options hook to parse the command line arguments and set
42 // options.
43 this->parse_args (argc, argv);
45 // Set the acceptor endpoint into listen mode (use the Singleton
46 // global Reactor...).
47 if (this->open (this->service_addr_, ACE_Reactor::instance (),
48 0, 0, 0,
49 &this->scheduling_strategy_,
50 ACE_TEXT ("Time Server"),
51 ACE_TEXT ("ACE time service")) == -1)
52 ACE_ERROR_RETURN ((LM_ERROR,
53 ACE_TEXT ("%n: %p on port %d\n"),
54 ACE_TEXT ("acceptor::open failed"),
55 this->service_addr_.get_port_number ()),
56 -1);
58 // Ignore SIGPIPE so that each <SVC_HANDLER> can handle this on its
59 // own.
60 ACE_Sig_Action sig ((ACE_SignalHandler) SIG_IGN, SIGPIPE);
61 ACE_UNUSED_ARG (sig);
63 ACE_INET_Addr server_addr;
65 // Figure out what port we're really bound to.
66 if (this->acceptor ().get_local_addr (server_addr) == -1)
67 ACE_ERROR_RETURN ((LM_ERROR,
68 ACE_TEXT ("%p\n"),
69 ACE_TEXT ("get_local_addr")),
70 -1);
72 ACE_DEBUG ((LM_DEBUG,
73 ACE_TEXT ("starting up Time Server at port %d on handle %d\n"),
74 server_addr.get_port_number (),
75 this->acceptor ().get_handle ()));
76 return 0;
79 // The following is a "Factory" used by the ACE_Service_Config and
80 // svc.conf file to dynamically initialize the state of the Time Server
82 ACE_SVC_FACTORY_DEFINE (ACE_TS_Server_Acceptor)
84 // Default constructor.
85 ACE_TS_Server_Handler::ACE_TS_Server_Handler (ACE_Thread_Manager *tm)
86 : ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> (tm)
88 ACE_TRACE ("ACE_TS_Server_Handler::ACE_TS_Server_Handler");
91 // Activate this instance of the ACE_TS_Server_Handler (called by the
92 // ACE_TS_Server_Acceptor).
94 /* VIRTUAL */ int
95 ACE_TS_Server_Handler::open (void *)
97 ACE_TRACE ("ACE_TS_Server_Handler::open");
99 ACE_INET_Addr client_addr;
101 // Determine the address of the client and display it.
102 if (this->peer ().get_remote_addr (client_addr) == -1)
103 ACE_ERROR_RETURN ((LM_ERROR,
104 ACE_TEXT ("%p\n"),
105 ACE_TEXT ("get_remote_addr")),
106 -1);
108 ACE_DEBUG ((LM_DEBUG,
109 ACE_TEXT ("(%t) accepted connection from host %C on fd %d\n"),
110 client_addr.get_host_name (),
111 this->peer ().get_handle ()));
113 // Call down to our parent to register ourselves with the Reactor.
114 if (ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>::open (0) == -1)
115 ACE_ERROR_RETURN ((LM_ERROR,
116 ACE_TEXT ("%p\n"),
117 ACE_TEXT ("open")),
118 -1);
119 return 0;
122 /* VIRTUAL */ int
123 ACE_TS_Server_Handler::send_request (ACE_Time_Request &request)
125 ACE_TRACE ("ACE_TS_Server_Handler::send_request");
126 void *buffer;
127 ssize_t length = request.encode (buffer);
129 if (length == -1)
130 ACE_ERROR_RETURN ((LM_ERROR,
131 ACE_TEXT ("%p\n"),
132 ACE_TEXT ("encode failed")),
133 -1);
135 // Transmit request via a blocking send.
137 if (this->peer ().send_n (buffer, length) != length)
138 ACE_ERROR_RETURN ((LM_ERROR,
139 ACE_TEXT ("%p\n"),
140 ACE_TEXT ("send_n failed")),
141 -1);
142 return 0;
145 // Give up waiting (e.g., when a timeout occurs or a client shuts down
146 // unexpectedly).
148 /* VIRTUAL */ int
149 ACE_TS_Server_Handler::abandon ()
151 ACE_TRACE ("ACE_TS_Server_Handler::abandon");
153 // Note we are using the time field to report the errno in case of
154 // failure.
155 ACE_Time_Request rq (-1, errno);
156 return this->send_request (rq);
159 // Enable clients to limit the amount of time they'll wait
160 /* VIRTUAL */ int
161 ACE_TS_Server_Handler::handle_timeout (const ACE_Time_Value &, const void *)
163 ACE_TRACE ("ACE_TS_Server_Handler::handle_timeout");
164 return this->abandon ();
167 // Return the underlying ACE_HANDLE.
169 /* VIRTUAL */ ACE_HANDLE
170 ACE_TS_Server_Handler::get_handle () const
172 ACE_TRACE ("ACE_TS_Server_Handler::get_handle");
173 return this->peer ().get_handle ();
176 // Dispatch the appropriate operation to handle the client request.
178 /* VIRTUAL */ int
179 ACE_TS_Server_Handler::dispatch ()
181 ACE_TRACE ("ACE_TS_Server_Handler::dispatch");
182 // Get the system time and then create an ACE_Time_Request
183 time_t t = ACE_OS::time (0);
184 ACE_Time_Request rq (ACE_Time_Request::TIME_UPDATE, t);
185 return this->send_request (rq);
188 // Receive, frame, and decode the client's request. Note, this method
189 // should use non-blocking I/O.
191 /* VIRTUAL */ int
192 ACE_TS_Server_Handler::recv_request ()
194 ACE_TRACE ("ACE_TS_Server_Handler::recv_request");
195 ssize_t const bytes_expected = this->time_request_.size ();
197 // Since Time_Request messages are fixed size, read the entire
198 // message in one go.
199 ssize_t const n = this->peer ().recv ((void *) &this->time_request_, bytes_expected);
200 if (n != bytes_expected)
202 switch (n)
204 case -1:
205 ACE_DEBUG ((LM_DEBUG,
206 ACE_TEXT ("****************** recv_request returned -1\n")));
207 ACE_FALLTHROUGH;
208 default:
209 ACE_ERROR ((LM_ERROR,
210 ACE_TEXT ("%p got %d bytes, expected %d bytes\n"),
211 ACE_TEXT ("recv failed"),
213 bytes_expected));
214 ACE_FALLTHROUGH;
215 case 0:
216 // We've shutdown unexpectedly, let's abandon the
217 // connection.
218 this->abandon ();
219 return -1;
220 /* NOTREACHED */
223 else
225 // Decode the request into host byte order.
226 if (this->time_request_.decode () == -1)
228 ACE_ERROR ((LM_ERROR,
229 ACE_TEXT ("%p\n"),
230 ACE_TEXT ("decode failed")));
231 return this->abandon ();
234 return 0;
237 // Callback method invoked by the ACE_Reactor when events arrive from
238 // the client.
240 /* VIRTUAL */ int
241 ACE_TS_Server_Handler::handle_input (ACE_HANDLE)
243 ACE_TRACE ("ACE_TS_Server_Handler::handle_input");
245 if (this->recv_request () == -1)
246 return -1;
247 else
248 return this->dispatch ();
251 ACE_TS_Server_Handler::~ACE_TS_Server_Handler ()
253 ACE_TRACE ("ACE_TS_Server_Handler::~ACE_TS_Server_Handler");
254 ACE_DEBUG ((LM_DEBUG,
255 ACE_TEXT ("closing down Handle %d\n"),
256 this->get_handle ()));