EMMA Coverage Report (generated Tue Dec 18 20:38:46 CET 2007)
[all classes][default package]

## COVERAGE SUMMARY FOR SOURCE FILE [Ping.java]

name | class, % | method, % | block, % | line, %
--- | --- | --- | --- | ---
Ping.java | 0% (0/4) | 0% (0/14) | 0% (0/422) | 0% (0/121)

### COVERAGE BREAKDOWN BY CLASS AND METHOD

name | class, % | method, % | block, % | line, %
--- | --- | --- | --- | ---
class Ping | 0% (0/1) | 0% (0/3) | 0% (0/93) | 0% (0/27)
<static initializer> |  | 0% (0/1) | 0% (0/5) | 0% (0/3)
Ping (): void |  | 0% (0/1) | 0% (0/3) | 0% (0/1)
main (String []): void |  | 0% (0/1) | 0% (0/85) | 0% (0/24)
class Ping$Connector | 0% (0/1) | 0% (0/6) | 0% (0/195) | 0% (0/60)
Ping$Connector (Ping$Printer): void |  | 0% (0/1) | 0% (0/20) | 0% (0/7)
add (Ping$Target): void |  | 0% (0/1) | 0% (0/55) | 0% (0/16)
processPendingTargets (): void |  | 0% (0/1) | 0% (0/42) | 0% (0/9)
processSelectedKeys (): void |  | 0% (0/1) | 0% (0/49) | 0% (0/15)
run (): void |  | 0% (0/1) | 0% (0/21) | 0% (0/10)
shutdown (): void |  | 0% (0/1) | 0% (0/8) | 0% (0/3)
class Ping$Printer | 0% (0/1) | 0% (0/3) | 0% (0/65) | 0% (0/18)
Ping$Printer (): void |  | 0% (0/1) | 0% (0/14) | 0% (0/5)
add (Ping$Target): void |  | 0% (0/1) | 0% (0/20) | 0% (0/4)
run (): void |  | 0% (0/1) | 0% (0/31) | 0% (0/9)
class Ping$Target | 0% (0/1) | 0% (0/2) | 0% (0/69) | 0% (0/16)
Ping$Target (String): void |  | 0% (0/1) | 0% (0/22) | 0% (0/8)
show (): void |  | 0% (0/1) | 0% (0/47) | 0% (0/8)

1 | /*
2 | * @(#)Ping.java 1.2 01/12/13
3 | * Connect to each of a list of hosts and measure the time required to complete
4 | * the connection. This example uses a selector and two additional threads in
5 | * order to demonstrate non-blocking connects and the multithreaded use of a
6 | * selector.
7 | *
8 | * Copyright 2001-2002 Sun Microsystems, Inc. All Rights Reserved.
9 | *
10 | * Redistribution and use in source and binary forms, with or
11 | * without modification, are permitted provided that the following
12 | * conditions are met:
13 | *
14 | * -Redistributions of source code must retain the above copyright
15 | * notice, this list of conditions and the following disclaimer.
16 | *
17 | * -Redistribution in binary form must reproduct the above copyright
18 | * notice, this list of conditions and the following disclaimer in
19 | * the documentation and/or other materials provided with the
20 | * distribution.
21 | *
22 | * Neither the name of Sun Microsystems, Inc. or the names of
23 | * contributors may be used to endorse or promote products derived
24 | * from this software without specific prior written permission.
25 | *
26 | * This software is provided "AS IS," without a warranty of any
27 | * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
28 | * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
29 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
30 | * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
31 | * DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR
32 | * RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR
33 | * ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
34 | * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
35 | * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
36 | * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
37 | * THE USE OF OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN
38 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
39 | *
40 | * You acknowledge that Software is not designed, licensed or
41 | * intended for use in the design, construction, operation or
42 | * maintenance of any nuclear facility.
43 | */
44 |
45 | import java.io.*;
46 | import java.net.*;
47 | import java.nio.channels.*;
48 | import java.util.*;
49 | import java.util.regex.Pattern;
50 |
51 | public class Ping {
52 |
53 | // The default daytime port
54 | static int DAYTIME_PORT = 13;
55 |
56 | // The port we'll actually use
57 | static int port = DAYTIME_PORT;
58 |
59 | // Representation of a ping target
60 | //
61 | static class Target {
62 |
63 | InetSocketAddress address;
64 | SocketChannel channel;
65 | Exception failure;
66 | long connectStart;
67 | long connectFinish = 0;
68 | boolean shown = false;
69 |
70 | Target(String host) {
71 | try {
72 | address = new InetSocketAddress(InetAddress.getByName(host),
73 | port);
74 | } catch (IOException x) {
75 | failure = x;
76 | }
77 | }
78 |
79 | void show() {
80 | String result;
81 | if (connectFinish != 0)
82 | result = Long.toString(connectFinish - connectStart) + "ms";
83 | else if (failure != null)
84 | result = failure.toString();
85 | else
86 | result = "Timed out";
87 | System.out.println(address + " : " + result);
88 | shown = true;
89 | }
90 |
91 | }
92 |
93 | // Thread for printing targets as they're heard from
94 | //
95 | static class Printer extends Thread {
96 | LinkedList<Target> pending = new LinkedList<Target>();
97 |
98 | Printer() {
99 | setName("Printer");
100 | setDaemon(true);
101 | }
102 |
103 | void add(Target t) {
104 | synchronized (pending) {
105 | pending.add(t);
106 | pending.notify();
107 | }
108 | }
109 |
110 | public void run() {
111 | try {
112 | for (;;) {
113 | Target t = null;
114 | synchronized (pending) {
115 | while (pending.size() == 0)
116 | pending.wait();
117 | t = (Target) pending.removeFirst();
118 | }
119 | t.show();
120 | }
121 | } catch (InterruptedException x) {
122 | return;
123 | }
124 | }
125 |
126 | }
127 |
128 | // Thread for connecting to all targets in parallel via a single selector
129 | //
130 | static class Connector extends Thread {
131 | Selector sel;
132 | Printer printer;
133 |
134 | // List of pending targets. We use this list because if we try to
135 | // register a channel with the selector while the connector thread is
136 | // blocked in the selector then we will block.
137 | //
138 | LinkedList<Target> pending = new LinkedList<Target>();
139 |
140 | Connector(Printer pr) throws IOException {
141 | printer = pr;
142 | sel = Selector.open();
143 | setName("Connector");
144 | }
145 |
146 | // Initiate a connection sequence to the given target and add the
147 | // target to the pending-target list
148 | //
149 | void add(Target t) {
150 | SocketChannel sc = null;
151 | try {
152 |
153 | // Open the channel, set it to non-blocking, initiate connect
154 | sc = SocketChannel.open();
155 | sc.configureBlocking(false);
156 | sc.connect(t.address);
157 |
158 | // Record the time we started
159 | t.channel = sc;
160 | t.connectStart = System.currentTimeMillis();
161 |
162 | // Add the new channel to the pending list
163 | synchronized (pending) {
164 | pending.add(t);
165 | }
166 |
167 | // Nudge the selector so that it will process the pending list
168 | sel.wakeup();
169 |
170 | } catch (IOException x) {
171 | if (sc != null) {
172 | try {
173 | sc.close();
174 | } catch (IOException xx) {
175 | }
176 | }
177 | t.failure = x;
178 | printer.add(t);
179 | }
180 | }
181 |
182 | // Process any targets in the pending list
183 | //
184 | void processPendingTargets() throws IOException {
185 | synchronized (pending) {
186 | while (pending.size() > 0) {
187 | Target t = (Target) pending.removeFirst();
188 | try {
189 |
190 | // Register the channel with the selector, indicating
191 | // interest in connection completion and attaching the
192 | // target object so that we can get the target back
193 | // after the key is added to the selector's
194 | // selected-key set
195 | t.channel.register(sel, SelectionKey.OP_CONNECT, t);
196 |
197 | } catch (IOException x) {
198 |
199 | // Something went wrong, so close the channel and
200 | // record the failure
201 | t.channel.close();
202 | t.failure = x;
203 | printer.add(t);
204 |
205 | }
206 |
207 | }
208 | }
209 | }
210 |
211 | // Process keys that have become selected
212 | //
213 | void processSelectedKeys() throws IOException {
214 | for (Iterator<SelectionKey> i = sel.selectedKeys().iterator(); i.hasNext();) {
215 |
216 | // Retrieve the next key and remove it from the set
217 | SelectionKey sk = (SelectionKey) i.next();
218 | i.remove();
219 |
220 | // Retrieve the target and the channel
221 | Target t = (Target) sk.attachment();
222 | SocketChannel sc = (SocketChannel) sk.channel();
223 |
224 | // Attempt to complete the connection sequence
225 | try {
226 | if (sc.finishConnect()) {
227 | sk.cancel();
228 | t.connectFinish = System.currentTimeMillis();
229 | sc.close();
230 | printer.add(t);
231 | }
232 | } catch (IOException x) {
233 | sc.close();
234 | t.failure = x;
235 | printer.add(t);
236 | }
237 | }
238 | }
239 |
240 | volatile boolean shutdown = false;
241 |
242 | // Invoked by the main thread when it's time to shut down
243 | //
244 | void shutdown() {
245 | shutdown = true;
246 | sel.wakeup();
247 | }
248 |
249 | // Connector loop
250 | //
251 | public void run() {
252 | for (;;) {
253 | try {
254 | int n = sel.select();
255 | if (n > 0)
256 | processSelectedKeys();
257 | processPendingTargets();
258 | if (shutdown) {
259 | sel.close();
260 | return;
261 | }
262 | } catch (IOException x) {
263 | x.printStackTrace();
264 | }
265 | }
266 | }
267 |
268 | }
269 |
270 | public static void main(String[] args) throws InterruptedException,
271 | IOException {
272 | if (args.length < 1) {
273 | System.err.println("Usage: java Ping [port] host...");
274 | return;
275 | }
276 | int firstArg = 0;
277 |
278 | // If the first argument is a string of digits then we take that
279 | // to be the port number to use
280 | if (Pattern.matches("[0-9]+", args[0])) {
281 | port = Integer.parseInt(args[0]);
282 | firstArg = 1;
283 | }
284 |
285 | // Create the threads and start them up
286 | Printer printer = new Printer();
287 | printer.start();
288 | Connector connector = new Connector(printer);
289 | connector.start();
290 |
291 | // Create the targets and add them to the connector
292 | LinkedList<Target> targets = new LinkedList<Target>();
293 | for (int i = firstArg; i < args.length; i++) {
294 | Target t = new Target(args[i]);
295 | targets.add(t);
296 | connector.add(t);
297 | }
298 |
299 | // Wait for everything to finish
300 | Thread.sleep(2000);
301 | connector.shutdown();
302 | connector.join();
303 |
304 | // Print status of targets that have not yet been shown
305 | for (Iterator<Target> i = targets.iterator(); i.hasNext();) {
306 | Target t = (Target) i.next();
307 | if (!t.shown)
308 | t.show();
309 | }
310 |
311 | }
312 |
313 | }

[all classes][default package]
EMMA 2.0.5312 EclEmma Fix 1 (C) Vladimir Roubtsov