powered by Jive Software

ConnectionListener.connectionClosedOnError can be called twice in a row

Listener.connectionClosedOnError can be called twice in a row:

In PacketWriter.java in void writePackets(Thread thisThread)

catch (IOException ioe){
            if (!done) {
                done = true;
                connection.packetReader.notifyConnectionError(ioe);
            }
        }

in PacketReader.java in void parsePackets(Thread thread)

catch (Exception e) {
            if (!done) {
                // Close the connection and notify connection listeners of the
                // error.
                notifyConnectionError(e);
            }
        }

The done flag is not shared between this two classes so the listener can be triggered twice:

void notifyConnectionError(Exception e) {
        done = true;
        // Closes the connection temporary. A reconnection is possible
        connection.shutdown(new Presence(Presence.Type.unavailable));
        // Print the stack trace to help catch the problem
        e.printStackTrace();
        // Notify connection listeners of the error.
        for (ConnectionListener listener : connectionListeners) {
            try {
                listener.connectionClosedOnError(e);
            }
            catch (Exception e2) {
                // Cath and print any exception so we can recover
                // from a faulty listener
                e2.printStackTrace();
            }
        }
    }

This happen to me while I use Smack in an Android application running on the T-Mobile G1 phone when I lose the network. I don’t think it’s intented to call twice the listener function, I never reproduced that in a desktop environment.

I proposed the following replacement code for notifyConnectionError:

+    synchronized void notifyConnectionError(Exception e) {
+        if (!done) {
+          done = true;
+          // Closes the connection temporary. A reconnection is possible
+          connection.shutdown(new Presence(Presence.Type.unavailable));
+          // Print the stack trace to help catch the problem
+          e.printStackTrace();
+          // Notify connection listeners of the error.
+          for (ConnectionListener listener : connectionListeners) {
+              try {
+                  listener.connectionClosedOnError(e);
+              }
+              catch (Exception e2) {
+                  // Cath and print any exception so we can recover
+                  // from a faulty listener
+                  e2.printStackTrace();
+              }
+          }

The full patch is attached in this thread.
PacketReader.java.patch (1930 Bytes)

This patch was commited (with minor modifications) into the community patch repo at

http://repo.or.cz/w/Smack.git?h=refs/heads/smack-3.1.1

as commit

http://repo.or.cz/w/Smack.git?a=commit;h=522e5d23dc8a95cf3d5168e3106f98fa782e156 8

Cheers,

Christopher

Chris,

Why is there a separate patch repo instead of sending the patch back to igniterealtime.org ? Where can I learn more about the repo itself? any blog? The repo and patch is not for android platform, is it? I will be glad if it is.