fixed concurrent modification when iterating over presences

This commit is contained in:
Daniel Gultsch 2020-05-30 10:57:22 +02:00
parent 8603d24bcb
commit 8edfc61346
5 changed files with 15 additions and 7 deletions

View file

@ -432,7 +432,7 @@ public class Account extends AbstractEntity implements AvatarService.Avatarable
public int activeDevicesWithRtpCapability() { public int activeDevicesWithRtpCapability() {
int i = 0; int i = 0;
for(Presence presence : getSelfContact().getPresences().getPresences().values()) { for(Presence presence : getSelfContact().getPresences().getPresences()) {
if (RtpCapability.check(presence) != RtpCapability.Capability.NONE) { if (RtpCapability.check(presence) != RtpCapability.Capability.NONE) {
i++; i++;
} }

View file

@ -11,8 +11,16 @@ import java.util.Map;
public class Presences { public class Presences {
private final Hashtable<String, Presence> presences = new Hashtable<>(); private final Hashtable<String, Presence> presences = new Hashtable<>();
public Hashtable<String, Presence> getPresences() { public List<Presence> getPresences() {
return this.presences; synchronized (this.presences) {
return new ArrayList<>(this.presences.values());
}
}
public Presence get(String resource) {
synchronized (this.presences) {
return this.presences.get(resource);
}
} }
public void updatePresence(String resource, Presence presence) { public void updatePresence(String resource, Presence presence) {

View file

@ -4468,8 +4468,8 @@ public class XmppConnectionService extends Service {
} }
private void injectServiceDiscoveryResult(Roster roster, String hash, String ver, ServiceDiscoveryResult disco) { private void injectServiceDiscoveryResult(Roster roster, String hash, String ver, ServiceDiscoveryResult disco) {
for (Contact contact : roster.getContacts()) { for (final Contact contact : roster.getContacts()) {
for (Presence presence : contact.getPresences().getPresences().values()) { for (final Presence presence : contact.getPresences().getPresences()) {
if (hash.equals(presence.getHash()) && ver.equals(presence.getVer())) { if (hash.equals(presence.getHash()) && ver.equals(presence.getVer())) {
presence.setServiceDiscoveryResult(disco); presence.setServiceDiscoveryResult(disco);
} }

View file

@ -417,7 +417,7 @@ public class JingleFileTransferConnection extends AbstractJingleConnection imple
final Jid jid = this.id.with; final Jid jid = this.id.with;
String resource = jid != null ? jid.getResource() : null; String resource = jid != null ? jid.getResource() : null;
if (resource != null) { if (resource != null) {
Presence presence = this.id.account.getRoster().getContact(jid).getPresences().getPresences().get(resource); Presence presence = this.id.account.getRoster().getContact(jid).getPresences().get(resource);
ServiceDiscoveryResult result = presence != null ? presence.getServiceDiscoveryResult() : null; ServiceDiscoveryResult result = presence != null ? presence.getServiceDiscoveryResult() : null;
return result == null ? Collections.emptyList() : result.getFeatures(); return result == null ? Collections.emptyList() : result.getFeatures();
} else { } else {

View file

@ -40,7 +40,7 @@ public class RtpCapability {
public static Capability check(final Contact contact) { public static Capability check(final Contact contact) {
final Presences presences = contact.getPresences(); final Presences presences = contact.getPresences();
Capability result = Capability.NONE; Capability result = Capability.NONE;
for(Presence presence : presences.getPresences().values()) { for(Presence presence : presences.getPresences()) {
Capability capability = check(presence); Capability capability = check(presence);
if (capability == Capability.VIDEO) { if (capability == Capability.VIDEO) {
result = capability; result = capability;