import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;


/** Pings client. Connects to the Pings server, retrieves addresses
 *  to be pinged, pings them and submits the results back to the server.
 *
 * @author Christian Hudon <chrish@pianocktail.org>
 */
public class PingsClient extends Thread {
    private ClientInfo m_client_info;
    private IcmpPinger m_pinger;
    private ServerProxy m_server_proxy;

    private AtomicBoolean m_is_running;
    private AtomicReference<String> m_nick;

    public PingsClient(String server_hostname, int server_port) {
        m_client_info = new ClientInfo();
        m_pinger = new IcmpPinger(m_client_info);
        m_server_proxy = new ServerProxy(server_hostname, server_port);

        m_is_running = new AtomicBoolean(true);
    }

    public void setNickname(String nick) {
        m_nick.set(nick);
    }

    public void halt() {
        m_is_running.set(false);
    }

    /// @todo Improve error handling when server_proxy raises an exception.
    public void run() {
        while (m_is_running.get()) {
            try {
                ServerProxy.Pings pings = m_server_proxy.getPings(m_client_info);

                for (int i = 0; i < pings.addresses.length; i++) {
                    m_pinger.clearPings();
                    m_pinger.ping(pings.addresses[i]);
                    pings.results[i] = m_pinger.getLastPings();
                }

                // Make sure nick is up-to-date before returning the ping results.
                m_client_info.setNickname(m_nick.get());
                m_server_proxy.submitResults(m_client_info, pings);
            }
            catch (IOException e) {
                // XXX Particularly bad. Thread will busy-loop if IOException keeps
                // getting raised in call to getPings.
            }
        }
    }
}

@@ -277,213 +277,863 @@
  * @
-author Christian Hudon %3Cchrish@pianocktail.org%3E%0A */%0Apublic class PingsClient extends Thread %7B%0A    private ClientInfo m_client_info;%0A    private IcmpPinger m_pinger;%0A    private ServerProxy m_server_proxy;%0A
+todo IMPORTANT: Give up after a certain number of errors in a row,%0A * instead of continuously hammering the server! If doing more than a few%0A * retries, exponential backoff would probably be a good idea too.%0A * @todo Improve error handling when server_proxy raises an exception.%0A * @author Christian Hudon %3Cchrish@pianocktail.org%3E%0A */%0Apublic class PingsClient extends Thread %7B%0A    // These variables are initialized in the constructor and then%0A    // only accessed by the PingsClient thread. No need for locking, etc.%0A    private ClientInfo m_client_info;%0A    private IcmpPinger m_pinger;%0A    private ServerProxy m_server_proxy;%0A%0A    // These variables are accessed both by the PingsClient thread and%0A    // by other threads using this class. They need to use something%0A    // like the Java Atomic types or other to prevent fun multithreading%0A    // bugs!
 %0A   
@@ -1645,84 +1645,8 @@
  %7D%0A%0A
-    /// @todo Improve error handling when server_proxy raises an exception.%0A
     
@@ -2332,42 +2332,21 @@
  // 
-XXX Particularly bad. T
+Avoid t
 hread 
-will 
 busy
@@ -2371,16 +2371,31 @@
 on keeps
+ getting raised
 %0A       
@@ -2405,31 +2405,16 @@
       //
- getting raised
  in call
@@ -2427,16 +2427,157 @@
 tPings.%0A
+                try %7B%0A                    sleep(1000);%0A                %7D%0A                catch (InterruptedException e2) %7B%0A                %7D%0A
         

Install a fix for busy-looping problem. Improve documentation of concurrent access restrictions for instance variables.