1 #ifndef ACE_SERVER_LOGGING_HANDLERT_C
2 #define ACE_SERVER_LOGGING_HANDLERT_C
4 #include "ace/config-all.h"
6 #include "ace/Get_Opt.h"
7 #include "ace/Log_Record.h"
8 #include "ace/CDR_Stream.h"
9 #include "Server_Logging_Handler_T.h"
10 #include "ace/Signal.h"
12 // Track number of requests.
13 template <ACE_PEER_STREAM_1
, class COUNTER
, ACE_SYNCH_DECL
, class LMR
>
14 COUNTER ACE_Server_Logging_Handler_T
<ACE_PEER_STREAM_2
, COUNTER
, ACE_SYNCH_USE
, LMR
>::request_count_
= (COUNTER
) 0;
16 template <ACE_PEER_STREAM_1
, class COUNTER
, ACE_SYNCH_DECL
, class LMR
>
17 ACE_Server_Logging_Handler_T
<ACE_PEER_STREAM_2
, COUNTER
, ACE_SYNCH_USE
, LMR
>::ACE_Server_Logging_Handler_T
18 (ACE_Thread_Manager
*,
20 // Initialize the CString to something that is not the empty string
21 // to avoid problems when calling fast_rep()
22 #if !defined (__GNUG__)
23 : receiver_ (receiver
, ACE_TString (ACE_TEXT(" "), 1))
25 : receiver_ (receiver
),
26 host_name_ (ACE_TString (ACE_TEXT (" "), 1))
27 #endif /* ! __GNUG__ */
31 // Callback routine for handling the reception of remote logging
34 template <ACE_PEER_STREAM_1
, class COUNTER
, ACE_SYNCH_DECL
, class LMR
> int
35 ACE_Server_Logging_Handler_T
<ACE_PEER_STREAM_2
, COUNTER
, ACE_SYNCH_USE
, LMR
>::handle_input (ACE_HANDLE
)
37 int result
= this->handle_logging_record ();
38 return result
>= 0 ? 0 : -1;
41 template <ACE_PEER_STREAM_1
, class COUNTER
, ACE_SYNCH_DECL
, class LMR
> const ACE_TCHAR
*
42 ACE_Server_Logging_Handler_T
<ACE_PEER_STREAM_2
, COUNTER
, ACE_SYNCH_USE
, LMR
>::host_name ()
44 #if !defined (__GNUG__)
45 return this->receiver_
.m_
.fast_rep ();
47 return this->host_name_
.fast_rep ();
48 #endif /* ! __GNUG__ */
51 template <ACE_PEER_STREAM_1
, class COUNTER
, ACE_SYNCH_DECL
, class LMR
> int
52 ACE_Server_Logging_Handler_T
<ACE_PEER_STREAM_2
, COUNTER
, ACE_SYNCH_USE
, LMR
>::handle_logging_record ()
54 ACE_Log_Record log_record
;
56 // We need to use the old two-read trick here since TCP sockets
57 // don't support framing natively. Allocate a message block for the
58 // payload; initially at least large enough to hold the header, but
59 // needs some room for alignment.
60 ACE_Message_Block
*payload_p
= 0;
61 ACE_Message_Block
*header_p
= 0;
62 ACE_NEW_RETURN (header_p
,
63 ACE_Message_Block (ACE_DEFAULT_CDR_BUFSIZE
),
66 std::unique_ptr
<ACE_Message_Block
> header (header_p
);
68 // Align the Message Block for a CDR stream
69 ACE_CDR::mb_align (header
.get ());
71 ACE_CDR::Boolean byte_order
;
72 ACE_CDR::ULong length
;
74 ssize_t count
= ACE::recv_n (this->peer ().get_handle (),
79 // Handle shutdown and error cases.
84 ACE_TEXT ("server logging daemon closing down at host %s\n"),
91 // Just fall through in this case..
95 header
->wr_ptr (8); // Reflect addition of 8 bytes.
97 // Create a CDR stream to parse the 8-byte header.
98 ACE_InputCDR
header_cdr (header
.get ());
100 // Extract the byte-order and use helper methods to disambiguate
101 // octet, booleans, and chars.
102 if (!(header_cdr
>> ACE_InputCDR::to_boolean (byte_order
)))
104 ACE_ERROR ((LM_ERROR
,
105 ACE_TEXT ("Can't extract byte_order\n")));
109 // Set the byte-order on the stream...
110 header_cdr
.reset_byte_order (byte_order
);
112 // Extract the length
113 if (!(header_cdr
>> length
))
115 ACE_ERROR ((LM_ERROR
,
116 ACE_TEXT ("Can't extract length\n")));
120 ACE_NEW_RETURN (payload_p
,
121 ACE_Message_Block (length
),
123 std::unique_ptr
<ACE_Message_Block
> payload (payload_p
);
125 // Ensure there's sufficient room for log record payload.
126 ACE_CDR::grow (payload
.get (), 8 + ACE_CDR::MAX_ALIGNMENT
+ length
);
128 // Use <recv_n> to obtain the contents.
129 if (ACE::recv_n (this->peer ().get_handle (),
133 ACE_ERROR ((LM_ERROR
,
135 ACE_TEXT ("recv_n()")));
139 payload
->wr_ptr (length
); // Reflect additional bytes
141 ACE_InputCDR
payload_cdr (payload
.get ());
142 payload_cdr
.reset_byte_order (byte_order
);
143 if (!(payload_cdr
>> log_record
)) // Finally extract the <ACE_log_record>.
145 ACE_ERROR ((LM_ERROR
,
146 ACE_TEXT ("Can't extract log_record\n")));
150 log_record
.length (length
);
152 // Send the log record to the log message receiver for processing.
153 if (ACE_BIT_ENABLED (ACE_Log_Msg::instance ()->flags (), ACE_Log_Msg::STDERR
))
154 receiver ().log_record (this->host_name (), log_record
);
156 ostream
*orig_ostream
= ACE_Log_Msg::instance ()->msg_ostream ();
157 receiver ().log_output (this->host_name (),
165 // We need to use the ol' two-read trick here since TCP sockets
166 // don't support framing natively. Note that the first call is just
167 // a "peek" -- we don't actually remove the data until the second
168 // call. Note that this code is portable as long as ACE_UNIT32 is
169 // always 32 bits on both the sender and receiver side.
171 switch (this->peer ().recv ((void *) &length
,
177 ACE_ERROR_RETURN ((LM_ERROR
,
178 ACE_TEXT ("%p at host %s\n"),
179 ACE_TEXT ("server logger"),
184 ACE_ERROR_RETURN ((LM_ERROR
,
185 ACE_TEXT ("closing log daemon at host %C\n"),
193 // Use ACE_NTOHL to get around bug in egcs 2.91.6x.
194 length
= ACE_NTOHL (length
);
196 ++this->request_count_
;
198 u_long count
= this->request_count_
;
199 ACE_DEBUG ((LM_DEBUG
,
200 ACE_TEXT ("request count = %d, length = %d\n"),
204 // Perform the actual <recv> this time.
205 ssize_t n
= this->peer ().recv_n ((void *) &lp
,
208 ACE_ERROR_RETURN ((LM_ERROR
,
209 ACE_TEXT ("%d != %d, %p at host %C\n"),
212 ACE_TEXT ("server logger"),
218 if (lp
.length () == n
)
220 // Send the log record to the log message receiver for
222 if (ACE_BIT_ENABLED (ACE_Log_Msg::instance ()->flags (),
223 ACE_Log_Msg::STDERR
))
224 receiver ().log_record (this->host_name (),
226 ostream
*orig_ostream
= ACE_Log_Msg::instance ()->msg_ostream ();
227 receiver ().log_output (this->host_name (),
233 ACE_TEXT ("error, lp.length = %d, n = %d\n"),
241 ACE_NOTREACHED (return -1;)
244 // Hook called by Server_Logging_Acceptor when connection is
247 template <ACE_PEER_STREAM_1
, class COUNTER
, ACE_SYNCH_DECL
, class LMR
> int
248 ACE_Server_Logging_Handler_T
<ACE_PEER_STREAM_2
, COUNTER
, ACE_SYNCH_USE
, LMR
>::open_common ()
250 // Shut off non-blocking IO if it was enabled...
251 if (this->peer ().disable (ACE_NONBLOCK
) == -1)
252 ACE_ERROR_RETURN ((LM_ERROR
,
254 ACE_TEXT ("disable")),
256 ACE_PEER_STREAM_ADDR client_addr
;
258 // Determine the address of the client and display it.
259 if (this->peer ().get_remote_addr (client_addr
) == -1)
260 ACE_ERROR_RETURN ((LM_ERROR
,
262 ACE_TEXT ("get_remote_addr")),
265 #if !defined (__GNUG__)
267 ACE_TString (ACE_TEXT_CHAR_TO_TCHAR (client_addr
.get_host_name ()));
270 ACE_TString (ACE_TEXT_CHAR_TO_TCHAR (client_addr
.get_host_name ()));
271 #endif /* ! __GNUG__ */
273 ACE_DEBUG ((LM_DEBUG
,
274 ACE_TEXT ("(%t) accepted connection from host %C on fd %d\n"),
275 client_addr
.get_host_name (),
276 this->peer ().get_handle ()));
281 template<class SLH
, class LMR
, class SST
>
282 ACE_Server_Logging_Acceptor_T
<SLH
, LMR
, SST
>::ACE_Server_Logging_Acceptor_T ()
286 template<class SLH
, class LMR
, class SST
> LMR
&
287 ACE_Server_Logging_Acceptor_T
<SLH
, LMR
, SST
>::receiver ()
292 template<class SLH
, class LMR
, class SST
> SST
&
293 ACE_Server_Logging_Acceptor_T
<SLH
, LMR
, SST
>::scheduling_strategy ()
295 #if !defined (__GNUG__)
298 return schedule_strategy_
;
299 #endif /* ! __GNUG__ */
302 template<class SLH
, class LMR
, class SST
> int
303 ACE_Server_Logging_Acceptor_T
<SLH
, LMR
, SST
>::init (int argc
, ACE_TCHAR
*argv
[])
305 ACE_TRACE ("ACE_Server_Logging_Acceptor_T<SLH, LMR, SST>::init");
307 // Use the options hook to parse the command line arguments and set
309 this->parse_args (argc
, argv
);
311 // Set the acceptor endpoint into listen mode (use the Singleton
312 // global Reactor...).
313 if (this->open (this->service_addr_
,
314 ACE_Reactor::instance (),
316 &this->scheduling_strategy(),
317 ACE_TEXT ("Logging Server"),
318 ACE_TEXT ("ACE logging service")) == -1)
319 ACE_ERROR_RETURN ((LM_ERROR
,
320 ACE_TEXT ("%n: %p on port %d\n"),
321 ACE_TEXT ("acceptor::open failed"),
322 this->service_addr_
.get_port_number ()),
324 // Ignore SIGPIPE so that each <SVC_HANDLER> can handle this on its
326 ACE_Sig_Action
sig ((ACE_SignalHandler
) SIG_IGN
, SIGPIPE
);
327 ACE_UNUSED_ARG (sig
);
329 ACE_INET_Addr server_addr
;
331 // Figure out what port we're really bound to.
332 if (this->acceptor ().get_local_addr (server_addr
) == -1)
333 ACE_ERROR_RETURN ((LM_ERROR
,
335 ACE_TEXT ("get_local_addr")),
337 ACE_DEBUG ((LM_DEBUG
,
338 ACE_TEXT ("starting up Logging Server at port %d on handle %d\n"),
339 server_addr
.get_port_number (),
340 this->acceptor ().get_handle ()));
344 template<class SLH
, class LMR
, class SST
> int
345 ACE_Server_Logging_Acceptor_T
<SLH
, LMR
, SST
>::parse_args (int argc
, ACE_TCHAR
*argv
[])
347 ACE_TRACE ("ACE_Server_Logging_Acceptor_T<SLH, LMR, SST>::parse_args");
349 int service_port
= ACE_DEFAULT_SERVER_PORT
;
351 ACE_LOG_MSG
->open (ACE_TEXT ("Logging Service"), ACE_LOG_MSG
->flags ());
353 ACE_Get_Opt
get_opt (argc
, argv
, ACE_TEXT ("p:"), 0);
355 for (int c
; (c
= get_opt ()) != -1; )
360 service_port
= ACE_OS::atoi (get_opt
.opt_arg ());
363 ACE_ERROR_RETURN ((LM_ERROR
,
364 ACE_TEXT ("%n:\n[-p server-port]\n")),
369 this->service_addr_
.set (service_port
);
373 template<class SERVER_LOGGING_HANDLER
, class LOG_MESSAGE_RECEIVER
, class SCHEDULE_STRATEGY
> int
374 ACE_Server_Logging_Acceptor_T
<SERVER_LOGGING_HANDLER
,
375 LOG_MESSAGE_RECEIVER
,
377 ::make_svc_handler (SERVER_LOGGING_HANDLER
*&handler
)
379 ACE_NEW_RETURN (handler
,
380 SERVER_LOGGING_HANDLER (ACE_Thread_Manager::instance (),
386 template<class LOG_MESSAGE_RECEIVER
>
387 ACE_Server_Logging_Handler
<LOG_MESSAGE_RECEIVER
>::ACE_Server_Logging_Handler (ACE_Thread_Manager
* tm
,
388 LOG_MESSAGE_RECEIVER
const& receiver
)
389 : ACE_Server_Logging_Handler_T
<LOGGING_PEER_STREAM
, u_long
, ACE_NULL_SYNCH
, LOG_MESSAGE_RECEIVER
>(tm
,
394 template<class LOG_MESSAGE_RECEIVER
>
395 ACE_Server_Logging_Handler
<LOG_MESSAGE_RECEIVER
>::ACE_Server_Logging_Handler(ACE_Thread_Manager
* tm
)
396 : ACE_Server_Logging_Handler_T
<LOGGING_PEER_STREAM
, u_long
, ACE_NULL_SYNCH
, LOG_MESSAGE_RECEIVER
>(tm
, LOG_MESSAGE_RECEIVER())
400 template<class LOG_MESSAGE_RECEIVER
> int
401 ACE_Server_Logging_Handler
<LOG_MESSAGE_RECEIVER
>::open (void *)
403 // call base class open_common
404 if (this->open_common () != 0)
407 // Register ourselves with the Reactor to enable subsequent
409 if (ACE_Reactor::instance ()->register_handler
410 (this, ACE_Event_Handler::READ_MASK
) == -1)
415 template<class LOG_MESSAGE_RECEIVER
>
416 ACE_Thr_Server_Logging_Handler
<LOG_MESSAGE_RECEIVER
>::ACE_Thr_Server_Logging_Handler (ACE_Thread_Manager
*tm
, LOG_MESSAGE_RECEIVER
const &receiver
)
417 : ACE_Server_Logging_Handler_T
<LOGGING_PEER_STREAM
, ACE_LOGGER_COUNTER
, ACE_LOGGER_SYNCH
, LOG_MESSAGE_RECEIVER
>(tm
, receiver
)
421 template<class LOG_MESSAGE_RECEIVER
>
422 ACE_Thr_Server_Logging_Handler
<LOG_MESSAGE_RECEIVER
>::ACE_Thr_Server_Logging_Handler (ACE_Thread_Manager
*tm
)
423 : ACE_Server_Logging_Handler_T
<LOGGING_PEER_STREAM
, ACE_LOGGER_COUNTER
, ACE_LOGGER_SYNCH
, LOG_MESSAGE_RECEIVER
>(tm
, LOG_MESSAGE_RECEIVER ())
427 template<class LOG_MESSAGE_RECEIVER
> int
428 ACE_Thr_Server_Logging_Handler
<LOG_MESSAGE_RECEIVER
>::open (void *)
430 // call base class open_common
431 if (this->open_common () != 0)
434 // Spawn a new thread of control to handle logging records with the
435 // client using a thread-per-connection concurrency model. Note
436 // that this implicitly uses the <ACE_Thread_Manager::instance> to
437 // control all the threads.
438 if (this->activate (THR_BOUND
| THR_DETACHED
) == -1)
439 ACE_ERROR_RETURN ((LM_ERROR
,
446 // Process remote logging records.
448 template<class LOG_MESSAGE_RECEIVER
> int
449 ACE_Thr_Server_Logging_Handler
<LOG_MESSAGE_RECEIVER
>::svc ()
453 // Loop until the client terminates the connection or an error occurs.
455 while ((result
= this->handle_input ()) == 0)
460 #endif /* ACE_SERVER_LOGGING_HANDLER_TT_C */