Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / ACE / apps / JAWS / stress_testing / benchd.cpp
blobd0b8fc575a79a1f1a08e4d382aaacf800c2a0584
1 // benchd: Adapted from the "ntalker" example.
2 // Sumedh Mungee
4 #include "ace/Process.h"
5 #include "ace/INET_Addr.h"
6 #include "ace/SOCK_Dgram_Mcast.h"
7 #include "ace/Reactor.h"
8 #include "ace/Get_Opt.h"
9 #include "ace/ARGV.h"
10 #include "ace/OS_NS_stdio.h"
12 #if defined (ACE_HAS_IP_MULTICAST)
13 // network interface to subscribe to
14 // this is hardware specific.
15 // use netstat (1M) to find whether your interface
16 // is le0 or ie0
18 // Maximum number of arguments supported for a request
19 static const int MAX_ARGS = 16;
20 // Name of the client benchmarking tool
21 static const char *TESTER = "http_tester";
22 static int QUIET = 0;
23 static const char *INTERFACE = "le0";
24 static const char *MCAST_ADDR = ACE_DEFAULT_MULTICAST_ADDR;
25 static const u_short UDP_PORT = ACE_DEFAULT_MULTICAST_PORT;
26 static const char *OUTPUT_FILE_NAME = "benchd.log";
27 static ACE_HANDLE OUTPUT_FILE;
29 // Handle both multicast and stdin events.
31 class Handle_Events : public ACE_Event_Handler
33 public:
34 Handle_Events (u_short udp_port,
35 const char *ip_addr,
36 const char *interface_,
37 ACE_Reactor &reactor);
38 ~Handle_Events ();
40 virtual int handle_input (ACE_HANDLE);
41 virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask);
43 private:
44 int serve (char *buf);
45 ACE_SOCK_Dgram_Mcast mcast_;
46 ACE_Handle_Set handle_set_;
49 int
50 Handle_Events::handle_input (ACE_HANDLE h)
52 char buf[BUFSIZ];
54 if (h == 0)
56 int readresult = ACE_OS::read (h, buf, BUFSIZ);
57 if (readresult > 0)
59 if (this->mcast_.send (buf, readresult) != readresult)
61 ACE_OS::perror ("send error");
62 return -1;
64 return 0;
66 else if (readresult == -1)
67 ACE_OS::perror ("can't read from STDIN");
69 return -1;
71 else
73 ACE_INET_Addr remote_addr;
75 // receive message from multicast group
76 int retcode = this->mcast_.recv (buf, sizeof buf, remote_addr);
78 if (retcode != -1)
81 cout << "received datagram from host " << remote_addr.get_host_name ()
82 << " on port " << remote_addr.get_port_number ()
83 << " bytes = " << retcode << endl;
85 serve (buf);
86 return 0;
89 ACE_OS::perror ("Something amiss.");
90 return -1;
94 int
95 Handle_Events::handle_close (ACE_HANDLE h, ACE_Reactor_Mask)
97 if (h == 0)
98 ACE_DEBUG ((LM_DEBUG, "STDIN_Events handle removed from reactor.\n"));
99 else
100 ACE_DEBUG ((LM_DEBUG, "Mcast_Events handle removed from reactor.\n"));
101 return 0;
104 Handle_Events::~Handle_Events ()
106 // ACE_OS::exit on error (bogus)...
108 if (this->mcast_.unsubscribe () == -1)
109 ACE_OS::perror ("unsubscribe fails"), ACE_OS::exit (1);
112 Handle_Events::Handle_Events (u_short udp_port,
113 const char *ip_addr,
114 const char *interface_,
115 ACE_Reactor &reactor)
117 // Create multicast address to listen on.
119 ACE_INET_Addr sockmc_addr (udp_port, ip_addr);
121 // subscribe to multicast group.
123 if (this->mcast_.subscribe (sockmc_addr, 1, interface_) == -1)
124 ACE_OS::perror ("can't subscribe to multicast group"), ACE_OS::exit (1);
126 // Disable loopbacks.
127 // if (this->mcast_.set_option (IP_MULTICAST_LOOP, 0) == -1 )
128 // ACE_OS::perror (" can't disable loopbacks " ), ACE_OS::exit (1);
130 if (!QUIET) {
131 this->handle_set_.set_bit (0);
133 this->handle_set_.set_bit (this->mcast_.get_handle ());
135 // Register callbacks with the ACE_Reactor.
136 if (reactor.register_handler (this->handle_set_,
137 this,
138 ACE_Event_Handler::READ_MASK) == -1)
139 ACE_OS::perror ("can't register events"), ACE_OS::exit (1);
143 // This method handles multicast requests..
144 // These requests are of the following form:
145 // command (arguments)
148 // currently only one is supported (and indeed needed :-)) http_tester
149 // arguments
152 Handle_Events::serve (char *buf)
154 ACE_ARGV arguments (buf);
156 if (ACE_OS::strcmp (arguments[0], TESTER) == 0)
158 ACE_Process_Options po;
159 ACE_Process p;
161 po.set_handles (ACE_INVALID_HANDLE, OUTPUT_FILE, OUTPUT_FILE);
162 po.command_line (arguments.argv ());
164 p.spawn (po);
165 return 0;
167 else
168 return -1;
171 static void
172 parse_args (int argc, ACE_TCHAR *argv[])
174 ACE_Get_Opt get_opt (argc, argv, ACE_TEXT("i:u:q"));
176 int c;
178 while ((c = get_opt ()) != -1)
179 switch (c)
181 case 'q':
182 QUIET = 1;
183 case 'i':
184 INTERFACE = get_opt.opt_arg ();
185 break;
186 case 'u':
187 // Usage, same as error
188 ACE_FALLTHROUGH;
189 default:
190 ACE_DEBUG ((LM_DEBUG, "%s -i interface\n", argv[0]));
191 ACE_OS::exit (1);
195 static sig_atomic_t done = 0;
197 // Signal handler.
199 extern "C" void
200 handler (int)
202 done = 1;
206 ACE_TMAIN (int argc, ACE_TCHAR *argv[])
208 ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGINT);
209 ACE_OS::signal (SIGCLD, SIG_IGN);
210 ACE_UNUSED_ARG (sa);
212 parse_args (argc, argv);
214 OUTPUT_FILE = ACE_OS::open (OUTPUT_FILE_NAME, O_CREAT | O_WRONLY, 0644);
215 if (OUTPUT_FILE == 0)
216 return 1;
218 ACE_Reactor reactor;
219 Handle_Events handle_events (UDP_PORT, MCAST_ADDR, INTERFACE, reactor);
221 // main loop
223 while (!done)
224 reactor.handle_events ();
226 ACE_OS::close (OUTPUT_FILE);
227 cout << "\nbenchd done.\n";
228 return 0;
230 #else
232 ACE_TMAIN (int argc, ACE_TCHAR *argv[])
234 ACE_ERROR ((LM_ERROR, "error: %s must be run on a platform that support IP multicast\n",
235 argv[0]));
236 return 0;
238 #endif /* ACE_HAS_IP_MULTICAST */