Merge pull request #2312 from jwillemsen/jwi-miopassert
[ACE_TAO.git] / ACE / examples / Logger / Acceptor-server / server_loggerd.cpp
blobdc3a2af3b01137b654900d292edd29fc4d572b38
1 // server_loggerd.cpp,v 4.29 2003/12/30 23:18:59 shuston Exp
3 // This server daemon collects, formats, and displays logging
4 // information forwarded from client daemons running on other hosts in
5 // the network. In addition, this example illustrates how to use the
6 // ACE_Reactor, ACE_Acceptor, ACE_Singleton, and the ACE_Test_and_Set
7 // components.
9 #include "ace/OS_NS_string.h"
10 #include "ace/Get_Opt.h"
11 #include "ace/Acceptor.h"
12 #include "ace/Null_Mutex.h"
13 #include "ace/SOCK_Acceptor.h"
14 #include "ace/Singleton.h"
15 #include "ace/CDR_Stream.h"
16 #include "ace/Test_and_Set.h"
18 // FUZZ: disable check_for_streams_include
19 #include "ace/streams.h"
21 #include "ace/Log_Record.h"
22 #include "ace/Test_and_Set.h"
24 #include "server_loggerd.h"
25 #include <memory>
27 // ----------------------------------------
29 // Return the port number.
31 u_short
32 Options::port ()
34 return this->port_;
37 // Parse the command-line options.
39 void
40 Options::parse_args (int argc, ACE_TCHAR *argv[])
42 this->port_ = ACE_DEFAULT_SERVER_PORT;
44 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT ("p:"));
46 for (int c; (c = get_opt ()) != -1; )
47 switch (c)
49 case 'p':
50 this->port_ = ACE_OS::atoi (get_opt.opt_arg ());
51 break;
52 default:
53 break;
57 // ----------------------------------------
59 // Our Reactor Singleton.
60 typedef ACE_Singleton<ACE_Reactor, ACE_Null_Mutex>
61 REACTOR;
63 // Our Options Singleton.
64 typedef ACE_Singleton<Options, ACE_Null_Mutex>
65 OPTIONS;
67 // Our ACE_Test_and_Set Singleton.
68 typedef ACE_Singleton<ACE_Test_and_Set <ACE_Null_Mutex, sig_atomic_t>, ACE_Null_Mutex>
69 QUIT_HANDLER;
71 // ----------------------------------------
73 // Specialize a Logging Acceptor.
74 typedef ACE_Acceptor <Logging_Handler, ACE_SOCK_ACCEPTOR>
75 Logging_Acceptor;
77 // Default constructor.
79 Logging_Handler::Logging_Handler ()
83 int
84 Logging_Handler::handle_timeout (const ACE_Time_Value &,
85 const void *arg)
87 #if defined (ACE_NDEBUG)
88 ACE_UNUSED_ARG (arg);
89 #endif /* ACE_NDEBUG */
91 ACE_ASSERT (arg == this);
92 ACE_DEBUG ((LM_DEBUG,
93 ACE_TEXT ("(%P|%t) handling timeout from this = %@\n"), this));
94 return 0;
97 // Perform the logging record receive.
99 int
100 Logging_Handler::handle_input (ACE_HANDLE)
102 ACE_Log_Record log_record;
104 // We need to use the old two-read trick here since TCP sockets
105 // don't support framing natively. Allocate a message block for the
106 // payload; initially at least large enough to hold the header, but
107 // needs some room for alignment.
108 ACE_Message_Block *payload_p = 0;
109 ACE_Message_Block *header_p = 0;
110 ACE_NEW_RETURN (header_p,
111 ACE_Message_Block (ACE_DEFAULT_CDR_BUFSIZE),
112 -1);
114 std::unique_ptr <ACE_Message_Block> header (header_p);
116 // Align the Message Block for a CDR stream
117 ACE_CDR::mb_align (header.get ());
119 ACE_CDR::Boolean byte_order;
120 ACE_CDR::ULong length;
122 ssize_t count = ACE::recv_n (this->peer ().get_handle (),
123 header->wr_ptr (),
125 switch (count)
127 // Handle shutdown and error cases.
128 default:
129 case -1:
130 case 0:
132 ACE_DEBUG ((LM_DEBUG,
133 ACE_TEXT ("server logging daemon closing down\n")));
135 return -1;
136 /* NOTREACHED */
138 case 8:
139 // Just fall through in this case..
140 break;
143 header->wr_ptr (8); // Reflect addition of 8 bytes.
145 // Create a CDR stream to parse the 8-byte header.
146 ACE_InputCDR header_cdr (header.get ());
148 // Extract the byte-order and use helper methods to disambiguate
149 // octet, booleans, and chars.
150 header_cdr >> ACE_InputCDR::to_boolean (byte_order);
152 // Set the byte-order on the stream...
153 header_cdr.reset_byte_order (byte_order);
155 // Extract the length
156 header_cdr >> length;
158 ACE_NEW_RETURN (payload_p,
159 ACE_Message_Block (length),
160 -1);
161 std::unique_ptr <ACE_Message_Block> payload (payload_p);
163 // Ensure there's sufficient room for log record payload.
164 ACE_CDR::grow (payload.get (), 8 + ACE_CDR::MAX_ALIGNMENT + length);
166 // Use <recv_n> to obtain the contents.
167 if (ACE::recv_n (this->peer ().get_handle (),
168 payload->wr_ptr (),
169 length) <= 0)
171 ACE_ERROR ((LM_ERROR,
172 ACE_TEXT ("%p\n"),
173 ACE_TEXT ("recv_n()")));
174 return -1;
177 payload->wr_ptr (length); // Reflect additional bytes
179 ACE_InputCDR payload_cdr (payload.get ());
180 payload_cdr.reset_byte_order (byte_order);
181 payload_cdr >> log_record; // Finally extract the <ACE_log_record>.
183 log_record.length (length);
185 log_record.print (ACE_TEXT_CHAR_TO_TCHAR (this->peer_name_), 1, stderr);
187 return 0;
191 Logging_Handler::open (void *)
193 ACE_INET_Addr addr;
195 if (this->peer ().get_remote_addr (addr) == -1)
196 return -1;
197 else
199 ACE_OS::strncpy (this->peer_name_,
200 addr.get_host_name (),
201 MAXHOSTNAMELEN + 1);
203 if (REACTOR::instance ()->register_handler (this, READ_MASK) == -1)
204 ACE_ERROR_RETURN ((LM_ERROR,
205 ACE_TEXT ("(%P|%t) can't register with reactor\n")),
206 -1);
207 else if (REACTOR::instance ()->schedule_timer
208 (this,
209 (const void *) this,
210 ACE_Time_Value (2),
211 ACE_Time_Value (2)) == -1)
212 ACE_ERROR_RETURN ((LM_ERROR,
213 ACE_TEXT ("(%P|%t) can't register with reactor\n")),
214 -1);
215 else
216 ACE_DEBUG ((LM_DEBUG,
217 ACE_TEXT ("(%P|%t) connected with %C\n"),
218 this->peer_name_));
219 return 0;
224 ACE_TMAIN (int argc, ACE_TCHAR *argv[])
226 // Acceptor factory.
227 Logging_Acceptor peer_acceptor;
229 OPTIONS::instance ()->parse_args (argc, argv);
231 // We need to pass in REACTOR::instance () here so that we don't use
232 // the default ACE_Reactor::instance ().
234 if (peer_acceptor.open
235 (ACE_INET_Addr (OPTIONS::instance ()->port ()),
236 REACTOR::instance ()) == -1)
237 ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("open")), -1);
239 // Register QUIT_HANDLER to receive SIGINT commands. When received,
240 // QUIT_HANDLER becomes "set" and thus, the event loop below will
241 // exit.
242 else if (REACTOR::instance ()->register_handler
243 (SIGINT, QUIT_HANDLER::instance ()) == -1)
244 ACE_ERROR_RETURN ((LM_ERROR,
245 ACE_TEXT ("registering service with ACE_Reactor\n")),
246 -1);
248 // Run forever, performing logging service.
250 ACE_DEBUG ((LM_DEBUG,
251 ACE_TEXT ("(%P|%t) starting up server logging daemon\n")));
253 // Perform logging service until QUIT_HANDLER receives SIGINT.
254 while (QUIT_HANDLER::instance ()->is_set () == 0)
255 REACTOR::instance ()->handle_events ();
257 ACE_DEBUG ((LM_DEBUG,
258 ACE_TEXT ("(%P|%t) shutting down server logging daemon\n")));
260 return 0;
263 ACE_SINGLETON_TEMPLATE_INSTANTIATE(ACE_Singleton, ACE_Reactor, ACE_Null_Mutex);
264 ACE_SINGLETON_TEMPLATE_INSTANTIATE(ACE_Singleton, Options, ACE_Null_Mutex);
265 #define ACE_Test_and_Set_type \
266 ACE_Test_and_Set<ACE_Null_Mutex, sig_atomic_t>
267 ACE_SINGLETON_TEMPLATE_INSTANTIATE(ACE_Singleton, ACE_Test_and_Set_type, ACE_Null_Mutex);