mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-22 14:22:05 +01:00
[muc] Prevent race condition on enter() by waiting
This prevents a race condition of enter() with the presence listern by waiting until all presences have been processed. Reported-by: Guus der Kinderen <guus@goodbytes.nl>
This commit is contained in:
parent
f12fe2264a
commit
7e311ab9df
1 changed files with 24 additions and 6 deletions
|
@ -149,6 +149,11 @@ public class MultiUserChat {
|
||||||
private EntityFullJid myRoomJid;
|
private EntityFullJid myRoomJid;
|
||||||
private StanzaCollector messageCollector;
|
private StanzaCollector messageCollector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to signal that the reflected self-presence was received <b>and</b> processed by us.
|
||||||
|
*/
|
||||||
|
private volatile boolean processedReflectedSelfPresence;
|
||||||
|
|
||||||
MultiUserChat(XMPPConnection connection, EntityBareJid room, MultiUserChatManager multiUserChatManager) {
|
MultiUserChat(XMPPConnection connection, EntityBareJid room, MultiUserChatManager multiUserChatManager) {
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
this.room = room;
|
this.room = room;
|
||||||
|
@ -216,13 +221,15 @@ public class MultiUserChat {
|
||||||
newAffiliation,
|
newAffiliation,
|
||||||
isUserStatusModification,
|
isUserStatusModification,
|
||||||
from);
|
from);
|
||||||
}
|
} else if (mucUser.getStatus().contains(MUCUser.Status.PRESENCE_TO_SELF_110)) {
|
||||||
else {
|
processedReflectedSelfPresence = true;
|
||||||
|
synchronized (this) {
|
||||||
|
notify();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// A new occupant has joined the room
|
// A new occupant has joined the room
|
||||||
if (!isUserStatusModification) {
|
for (ParticipantStatusListener listener : participantStatusListeners) {
|
||||||
for (ParticipantStatusListener listener : participantStatusListeners) {
|
listener.joined(from);
|
||||||
listener.joined(from);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -376,6 +383,7 @@ public class MultiUserChat {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
processedReflectedSelfPresence = false;
|
||||||
StanzaCollector presenceStanzaCollector = null;
|
StanzaCollector presenceStanzaCollector = null;
|
||||||
final Presence reflectedSelfPresence;
|
final Presence reflectedSelfPresence;
|
||||||
try {
|
try {
|
||||||
|
@ -398,6 +406,16 @@ public class MultiUserChat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
synchronized (presenceListener) {
|
||||||
|
// Only continue after we have received *and* processed the reflected self-presence. Since presences are
|
||||||
|
// handled in an extra listener, we may return from enter() without having processed all presences of the
|
||||||
|
// participants, resulting in a e.g. to low participant counter after enter(). Hence we wait here until the
|
||||||
|
// processing is done.
|
||||||
|
while (!processedReflectedSelfPresence) {
|
||||||
|
presenceListener.wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This presence must be send from a full JID. We use the resourcepart of this JID as nick, since the room may
|
// This presence must be send from a full JID. We use the resourcepart of this JID as nick, since the room may
|
||||||
// performed roomnick rewriting
|
// performed roomnick rewriting
|
||||||
Resourcepart receivedNickname = reflectedSelfPresence.getFrom().getResourceOrThrow();
|
Resourcepart receivedNickname = reflectedSelfPresence.getFrom().getResourceOrThrow();
|
||||||
|
|
Loading…
Reference in a new issue