sync around individual calls instead of synchronizing entire object

This commit is contained in:
Daniel Gultsch 2016-05-19 10:47:03 +02:00
parent ef27055434
commit 8d595c1fc2

View file

@ -28,6 +28,7 @@ public class MucOptions {
public void changeAffiliation(Jid jid, Affiliation affiliation) { public void changeAffiliation(Jid jid, Affiliation affiliation) {
User user = findUserByRealJid(jid); User user = findUserByRealJid(jid);
synchronized (users) {
if (user != null && user.getRole() == Role.NONE) { if (user != null && user.getRole() == Role.NONE) {
users.remove(user); users.remove(user);
if (affiliation.ranks(Affiliation.MEMBER)) { if (affiliation.ranks(Affiliation.MEMBER)) {
@ -36,6 +37,7 @@ public class MucOptions {
} }
} }
} }
}
public enum Affiliation { public enum Affiliation {
OWNER("owner", 4, R.string.owner), OWNER("owner", 4, R.string.owner),
@ -155,10 +157,6 @@ public class MucOptions {
this.realJid = jid != null ? jid.toBareJid() : null; this.realJid = jid != null ? jid.toBareJid() : null;
} }
public Jid getRealJid() {
return this.realJid;
}
public Role getRole() { public Role getRole() {
return this.role; return this.role;
} }
@ -299,10 +297,14 @@ public class MucOptions {
return getName().compareToIgnoreCase(another.getName()); return getName().compareToIgnoreCase(another.getName());
} }
} }
public Jid getRealJid() {
return realJid;
}
} }
private Account account; private Account account;
private final Set<User> users = Collections.synchronizedSet(new HashSet<User>()); private final Set<User> users = new HashSet<>();
private final List<String> features = new ArrayList<>(); private final List<String> features = new ArrayList<>();
private Data form = new Data(); private Data form = new Data();
private Conversation conversation; private Conversation conversation;
@ -373,6 +375,7 @@ public class MucOptions {
public User deleteUser(Jid jid) { public User deleteUser(Jid jid) {
User user = findUserByFullJid(jid); User user = findUserByFullJid(jid);
if (user != null) { if (user != null) {
synchronized (users) {
users.remove(user); users.remove(user);
if (user.affiliation.ranks(Affiliation.MEMBER) && user.realJid != null) { if (user.affiliation.ranks(Affiliation.MEMBER) && user.realJid != null) {
user.role = Role.NONE; user.role = Role.NONE;
@ -381,6 +384,7 @@ public class MucOptions {
users.add(user); users.add(user);
} }
} }
}
return user; return user;
} }
@ -389,30 +393,42 @@ public class MucOptions {
if (user.fullJid == null && user.realJid != null) { if (user.fullJid == null && user.realJid != null) {
old = findUserByRealJid(user.realJid); old = findUserByRealJid(user.realJid);
if (old != null) { if (old != null) {
if (old.fullJid != null) {
return; //don't add. user already exists return; //don't add. user already exists
} else {
synchronized (users) {
users.remove(old);
}
}
} }
} else if (user.realJid != null) { } else if (user.realJid != null) {
old = findUserByRealJid(user.realJid); old = findUserByRealJid(user.realJid);
synchronized (users) {
if (old != null && old.fullJid == null) { if (old != null && old.fullJid == null) {
users.remove(old); users.remove(old);
} }
} }
}
old = findUserByFullJid(user.getFullJid()); old = findUserByFullJid(user.getFullJid());
synchronized (this.users) {
if (old != null) { if (old != null) {
users.remove(old); users.remove(old);
} }
this.users.add(user); this.users.add(user);
} }
}
public User findUserByFullJid(Jid jid) { public User findUserByFullJid(Jid jid) {
if (jid == null) { if (jid == null) {
return null; return null;
} }
for(User user : users) { synchronized (users) {
for (User user : users) {
if (jid.equals(user.getFullJid())) { if (jid.equals(user.getFullJid())) {
return user; return user;
} }
} }
}
return null; return null;
} }
@ -420,11 +436,13 @@ public class MucOptions {
if (jid == null) { if (jid == null) {
return null; return null;
} }
for(User user : users) { synchronized (users) {
if (jid.equals(user.getRealJid())) { for (User user : users) {
if (jid.equals(user.realJid)) {
return user; return user;
} }
} }
}
return null; return null;
} }
@ -446,18 +464,20 @@ public class MucOptions {
} }
public ArrayList<User> getUsers(boolean includeOffline) { public ArrayList<User> getUsers(boolean includeOffline) {
synchronized (users) {
if (includeOffline) { if (includeOffline) {
return new ArrayList<>(users); return new ArrayList<>(users);
} else { } else {
ArrayList<User> onlineUsers = new ArrayList<>(); ArrayList<User> onlineUsers = new ArrayList<>();
for(User user : users) { for (User user : users) {
if(user.getRole().ranks(Role.PARTICIPANT)) { if (user.getRole().ranks(Role.PARTICIPANT)) {
onlineUsers.add(user); onlineUsers.add(user);
} }
} }
return onlineUsers; return onlineUsers;
} }
} }
}
public List<User> getUsers(int max) { public List<User> getUsers(int max) {
ArrayList<User> users = getUsers(); ArrayList<User> users = getUsers();
@ -465,7 +485,9 @@ public class MucOptions {
} }
public int getUserCount() { public int getUserCount() {
return this.users.size(); synchronized (users) {
return users.size();
}
} }
public String getProposedNick() { public String getProposedNick() {
@ -501,7 +523,9 @@ public class MucOptions {
} }
public void setOffline() { public void setOffline() {
synchronized (users) {
this.users.clear(); this.users.clear();
}
this.error = Error.NO_RESPONSE; this.error = Error.NO_RESPONSE;
this.isOnline = false; this.isOnline = false;
} }
@ -519,7 +543,7 @@ public class MucOptions {
} }
public String createNameFromParticipants() { public String createNameFromParticipants() {
if (users.size() >= 2) { if (getUserCount() >= 2) {
List<String> names = new ArrayList<>(); List<String> names = new ArrayList<>();
for (User user : getUsers(5)) { for (User user : getUsers(5)) {
Contact contact = user.getContact(); Contact contact = user.getContact();
@ -558,20 +582,24 @@ public class MucOptions {
} }
public boolean pgpKeysInUse() { public boolean pgpKeysInUse() {
for (User user : this.users) { synchronized (users) {
for (User user : users) {
if (user.getPgpKeyId() != 0) { if (user.getPgpKeyId() != 0) {
return true; return true;
} }
} }
}
return false; return false;
} }
public boolean everybodyHasKeys() { public boolean everybodyHasKeys() {
for (User user : this.users) { synchronized (users) {
for (User user : users) {
if (user.getPgpKeyId() == 0) { if (user.getPgpKeyId() == 0) {
return false; return false;
} }
} }
}
return true; return true;
} }
@ -588,7 +616,7 @@ public class MucOptions {
return account.getJid().toBareJid(); return account.getJid().toBareJid();
} }
User user = findUserByFullJid(jid); User user = findUserByFullJid(jid);
return user == null ? null : user.getRealJid(); return user == null ? null : user.realJid;
} }
public String getPassword() { public String getPassword() {
@ -616,9 +644,11 @@ public class MucOptions {
public List<Jid> getMembers() { public List<Jid> getMembers() {
ArrayList<Jid> members = new ArrayList<>(); ArrayList<Jid> members = new ArrayList<>();
for(User user : users) { synchronized (users) {
if (user.affiliation.ranks(Affiliation.MEMBER) && user.getRealJid() != null) { for (User user : users) {
members.add(user.getRealJid()); if (user.affiliation.ranks(Affiliation.MEMBER) && user.realJid != null) {
members.add(user.realJid);
}
} }
} }
return members; return members;