Prevent deadlock when adding/removing viewers very fast

Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
TheMode 2021-09-20 18:42:31 +02:00
parent e65c9f6a79
commit 4e58d61345

View File

@ -131,11 +131,6 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler
private final Acquirable<Entity> acquirable = Acquirable.of(this); private final Acquirable<Entity> acquirable = Acquirable.of(this);
/**
* Lock used to support #switchEntityType
*/
private final Object entityTypeLock = new Object();
public Entity(@NotNull EntityType entityType, @NotNull UUID uuid) { public Entity(@NotNull EntityType entityType, @NotNull UUID uuid) {
this.id = generateId(); this.id = generateId();
this.entityType = entityType; this.entityType = entityType;
@ -310,9 +305,7 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler
@Override @Override
public final boolean addViewer(@NotNull Player player) { public final boolean addViewer(@NotNull Player player) {
synchronized (this.entityTypeLock) { return addViewer0(player);
return addViewer0(player);
}
} }
protected boolean addViewer0(@NotNull Player player) { protected boolean addViewer0(@NotNull Player player) {
@ -338,9 +331,7 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler
@Override @Override
public final boolean removeViewer(@NotNull Player player) { public final boolean removeViewer(@NotNull Player player) {
synchronized (this.entityTypeLock) { return removeViewer0(player);
return removeViewer0(player);
}
} }
protected boolean removeViewer0(@NotNull Player player) { protected boolean removeViewer0(@NotNull Player player) {
@ -369,16 +360,14 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler
* *
* @param entityType the new entity type * @param entityType the new entity type
*/ */
public void switchEntityType(@NotNull EntityType entityType) { public synchronized void switchEntityType(@NotNull EntityType entityType) {
synchronized (entityTypeLock) { this.entityType = entityType;
this.entityType = entityType; this.metadata = new Metadata(this);
this.metadata = new Metadata(this); this.entityMeta = EntityTypeImpl.createMeta(entityType, this, this.metadata);
this.entityMeta = EntityTypeImpl.createMeta(entityType, this, this.metadata);
Set<Player> viewers = new HashSet<>(getViewers()); Set<Player> viewers = new HashSet<>(getViewers());
getViewers().forEach(this::removeViewer0); getViewers().forEach(this::removeViewer0);
viewers.forEach(this::addViewer0); viewers.forEach(this::addViewer0);
}
} }
@NotNull @NotNull