1
0
Fork 0
mirror of https://codeberg.org/Mercury-IM/Smack synced 2024-11-08 01:05:58 +01:00

Only wait in Roster's presence listener if loading

otherwhise skip waitUntilLoaded(). This introduces RosterState.

SMACK-681
This commit is contained in:
Florian Schmaus 2015-07-03 17:35:20 +02:00
parent 36d99ecab3
commit ae944d3546

View file

@ -145,9 +145,16 @@ public class Roster extends Manager {
*/ */
private final Object rosterListenersAndEntriesLock = new Object(); private final Object rosterListenersAndEntriesLock = new Object();
// The roster is marked as initialized when at least a single roster packet private enum RosterState {
// has been received and processed. uninitialized,
private boolean loaded = false; loading,
loaded,
}
/**
* The current state of the roster.
*/
private RosterState rosterState = RosterState.uninitialized;
private final PresencePacketListener presencePacketListener = new PresencePacketListener(); private final PresencePacketListener presencePacketListener = new PresencePacketListener();
@ -290,9 +297,11 @@ public class Roster extends Manager {
if (rosterStore != null && isRosterVersioningSupported()) { if (rosterStore != null && isRosterVersioningSupported()) {
packet.setVersion(rosterStore.getRosterVersion()); packet.setVersion(rosterStore.getRosterVersion());
} }
rosterState = RosterState.loading;
connection.sendIqWithResponseCallback(packet, new RosterResultListener(), new ExceptionCallback() { connection.sendIqWithResponseCallback(packet, new RosterResultListener(), new ExceptionCallback() {
@Override @Override
public void processException(Exception exception) { public void processException(Exception exception) {
rosterState = RosterState.uninitialized;
LOGGER.log(Level.SEVERE, "Exception reloading roster" , exception); LOGGER.log(Level.SEVERE, "Exception reloading roster" , exception);
} }
}); });
@ -333,12 +342,12 @@ public class Roster extends Manager {
protected boolean waitUntilLoaded() throws InterruptedException { protected boolean waitUntilLoaded() throws InterruptedException {
long waitTime = connection().getPacketReplyTimeout(); long waitTime = connection().getPacketReplyTimeout();
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
while (!loaded) { while (!isLoaded()) {
if (waitTime <= 0) { if (waitTime <= 0) {
break; break;
} }
synchronized (this) { synchronized (this) {
if (!loaded) { if (!isLoaded()) {
wait(waitTime); wait(waitTime);
} }
} }
@ -356,7 +365,7 @@ public class Roster extends Manager {
* @since 4.1 * @since 4.1
*/ */
public boolean isLoaded() { public boolean isLoaded() {
return loaded; return rosterState == RosterState.loaded;
} }
/** /**
@ -963,7 +972,7 @@ public class Roster extends Manager {
} }
} }
} }
loaded = false; rosterState = RosterState.uninitialized;
} }
/** /**
@ -1177,15 +1186,16 @@ public class Roster extends Manager {
// Try to ensure that the roster is loaded when processing presence stanzas. While the // Try to ensure that the roster is loaded when processing presence stanzas. While the
// presence listener is synchronous, the roster result listener is not, which means that // presence listener is synchronous, the roster result listener is not, which means that
// the presence listener may be invoked with a not yet loaded roster. // the presence listener may be invoked with a not yet loaded roster.
boolean loaded; if (rosterState == RosterState.loading) {
try { try {
loaded = waitUntilLoaded(); waitUntilLoaded();
}
catch (InterruptedException e) {
LOGGER.log(Level.INFO, "Presence listener was interrupted", e);
}
} }
catch (InterruptedException e) { if (!isLoaded()) {
LOGGER.log(Level.INFO, "Presence listener was interrupted", e);
loaded = Roster.this.loaded;
}
if (loaded) {
LOGGER.warning("Roster not loaded while processing presence stanza"); LOGGER.warning("Roster not loaded while processing presence stanza");
} }
final XMPPConnection connection = connection(); final XMPPConnection connection = connection();
@ -1350,7 +1360,7 @@ public class Roster extends Manager {
} }
} }
loaded = true; rosterState = RosterState.loaded;
synchronized (Roster.this) { synchronized (Roster.this) {
Roster.this.notifyAll(); Roster.this.notifyAll();
} }