Patch: Fixed Race Conditions in Roster Listener

Hi,

I’‘ve come to the conclusion that if I need some fixes in Smack in a timely manner, I have to do it myself. I’'ll keep posting my changes here in the hopes that they will be integrated some time into the main tree. Right now my version here is looking more like a fork every day (I think there are three or four patches missing from the main tree), I hope that this is not permanent.

This time I’'ve worked on fixing the race condition issue on the roster listener in a clean way. After connecting to the server, but before logging in, you have to call initializeRoster() on the connection to get the roster object that will be used afterwards, in order to add your listener and set the subscription mode early enough.

Note that the roster object will be discarded if you choose to log in anonymously instead.

  • …/smack-dev-2.2.1/source/org/jivesoftware/smack/XMPPConnection.java Mon Jun 12 23:13:15 2006

— source/org/jivesoftware/smack/XMPPConnection.java Sun Jul 16 12:33:09 2006


  • 449,455 ****

— 461,468 -


}

// Create the roster.

  •     if(this.roster == null)
    
  •         this.roster = new Roster(this);
    
  •     this.roster = new Roster(this);
    

roster.reload();

// Set presence to online.


  • 526,531 ****

— 539,568 -


debugger.userHasLogged(user);

}

}

  • /**
    
  •  * Returns the roster object that will be used after log in. This avoids the
    
  •  * race condition with receiving roster update packages before being able to register
    
  •  * the roster listener.
    
  •  * Note that this object will be useless when logging in anonymously afterwards.
    
  •  * It should only be used when the next action will be login().
    
  •  *
    
  •  * @return The roster object that will be used after logging in.
    
  •  *
    
  •  * @throws IllegalStateException if not connected to the server, or already logged in
    
  •  *      to the server (use getRoster() instead when already connected).
    
  •  */
    
  • public Roster initializeRoster() {
    
  •     if (!isConnected()) {
    
  •         throw new IllegalStateException("Not connected to server.");
    
  •     }
    
  •     if (authenticated) {
    
  •         throw new IllegalStateException("Already logged in to server.");
    
  •     }
    
  •     if(this.roster == null)
    
  •         this.roster = new Roster(this);
    
  •     return this.roster;
    
  • }
    

/**

  • Returns the roster for the user logged into the server. If the user has not yet

/code

Thanks for the detailed report and suggested fix! I’'ve filed this as SMACK-156.

-Matt