1 #include "ace/Log_Msg.h"
2 #include "ace/Message_Block.h"
3 #include "ace/Log_Record.h"
4 #include "ace/OS_NS_string.h"
5 #include "ace/CDR_Stream.h"
8 #include "Logging_Handler.h"
9 #include "Reactor_Singleton.h"
11 Logging_Handler::~Logging_Handler ()
13 // Make sure there are no timers.
14 REACTOR::instance ()->cancel_timer (this);
16 this->cli_stream_
.close ();
19 // Extract the underlying ACE_SOCK_Stream (e.g., for purposes of
22 Logging_Handler::peer ()
24 return this->cli_stream_
;
28 Logging_Handler::handle_timeout (const ACE_Time_Value
&,
31 #if defined (ACE_NDEBUG)
33 #endif /* ACE_NDEBUG */
35 ACE_ASSERT (arg
== this);
36 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("(%P|%t) handling timeout from this = %@\n"),
41 // Perform the logging record receive.
44 Logging_Handler::handle_input (ACE_HANDLE
)
46 ACE_Log_Record log_record
;
48 // We need to use the old two-read trick here since TCP sockets
49 // don't support framing natively. Allocate a message block for the
50 // payload; initially at least large enough to hold the header, but
51 // needs some room for alignment.
52 ACE_Message_Block
*payload_p
= 0;
53 ACE_Message_Block
*header_p
= 0;
54 ACE_NEW_RETURN (header_p
,
55 ACE_Message_Block (ACE_DEFAULT_CDR_BUFSIZE
),
58 std::unique_ptr
<ACE_Message_Block
> header (header_p
);
60 // Align the Message Block for a CDR stream
61 ACE_CDR::mb_align (header
.get ());
63 ACE_CDR::Boolean byte_order
;
64 ACE_CDR::ULong length
;
66 ssize_t count
= ACE::recv_n (this->peer ().get_handle (),
71 // Handle shutdown and error cases.
77 ACE_TEXT ("server logging daemon closing down\n")));
83 // Just fall through in this case..
87 header
->wr_ptr (8); // Reflect addition of 8 bytes.
89 // Create a CDR stream to parse the 8-byte header.
90 ACE_InputCDR
header_cdr (header
.get ());
92 // Extract the byte-order and use helper methods to disambiguate
93 // octet, booleans, and chars.
94 header_cdr
>> ACE_InputCDR::to_boolean (byte_order
);
96 // Set the byte-order on the stream...
97 header_cdr
.reset_byte_order (byte_order
);
100 header_cdr
>> length
;
102 ACE_NEW_RETURN (payload_p
,
103 ACE_Message_Block (length
),
105 std::unique_ptr
<ACE_Message_Block
> payload (payload_p
);
107 // Ensure there's sufficient room for log record payload.
108 ACE_CDR::grow (payload
.get (), 8 + ACE_CDR::MAX_ALIGNMENT
+ length
);
110 // Use <recv_n> to obtain the contents.
111 if (ACE::recv_n (this->peer ().get_handle (),
115 ACE_ERROR ((LM_ERROR
,
117 ACE_TEXT ("recv_n()")));
121 payload
->wr_ptr (length
); // Reflect additional bytes
123 ACE_InputCDR
payload_cdr (payload
.get ());
124 payload_cdr
.reset_byte_order (byte_order
);
125 payload_cdr
>> log_record
; // Finally extract the <ACE_log_record>.
127 log_record
.length (length
);
129 log_record
.print (ACE_TEXT_CHAR_TO_TCHAR (this->host_name_
), 1, stderr
);
134 // Extract underlying device descriptor.
137 Logging_Handler::get_handle () const
139 return this->cli_stream_
.get_handle ();
143 Logging_Handler::open ()
147 if (this->cli_stream_
.get_remote_addr (addr
) == -1)
151 ACE_OS::strncpy (this->host_name_
,
152 addr
.get_host_name (),
155 if (REACTOR::instance ()->register_handler (this, READ_MASK
) == -1)
156 ACE_ERROR_RETURN ((LM_ERROR
,
157 ACE_TEXT ("(%P|%t) can't register with reactor\n")),
159 else if (REACTOR::instance ()->schedule_timer
160 (this, (const void *) this,
162 ACE_Time_Value (2)) == -1)
163 ACE_ERROR_RETURN ((LM_ERROR
,
164 ACE_TEXT ("(%P|%t) can't register with reactor\n")),
167 ACE_DEBUG ((LM_DEBUG
,
168 ACE_TEXT ("(%P|%t) connected with %C\n"),
174 // Perform termination activities when deregistered from the
177 Logging_Handler::handle_close (ACE_HANDLE
, ACE_Reactor_Mask
)
179 // Must have been allocated dynamically
184 // Perform termination activities when close fails.
186 Logging_Handler::close ()
188 return this->handle_close ();