mirror of
https://github.com/PlayPro/CoreProtect.git
synced 2026-10-28 09:44:56 +00:00
Allocate world, material, blockdata, art and entity ids under one lock (#1009)
The id allocators read the counter, add one and store it without a lock, so two threads that see new names at the same time (region threads on Folia, lookup and API threads everywhere) can give the same id to two different names. Allocation now holds the ConfigHandler monitor reloadAndGetId already uses, with a re-check, and queues the insert after releasing it.
This commit is contained in:
1 parent
96eec2b768
commit
97fced4cb6
3 files changed
+66
-25
No files matched your search
@@ -38,18 +38,26 @@ public class EntityUtils extends Queue {
|
||||
id = ConfigHandler.entities.get(name);
|
||||
}
|
||||
else if (internal) {
|
||||
// Same monitor as reloadAndGetId, so two threads cannot allocate the same id
|
||||
synchronized (ConfigHandler.class) {
|
||||
Integer existing = ConfigHandler.entities.get(name);
|
||||
if (existing != null) {
|
||||
return existing;
|
||||
}
|
||||
|
||||
// Check if another server has already added this entity (multi-server setup)
|
||||
id = ConfigHandler.reloadAndGetId(ConfigHandler.CacheType.ENTITIES, name);
|
||||
if (id != -1) {
|
||||
return id;
|
||||
}
|
||||
|
||||
int entityID = ConfigHandler.entityId + 1;
|
||||
ConfigHandler.entities.put(name, entityID);
|
||||
ConfigHandler.entitiesReversed.put(entityID, name);
|
||||
ConfigHandler.entityId = entityID;
|
||||
Queue.queueEntityInsert(entityID, name);
|
||||
id = ConfigHandler.entities.get(name);
|
||||
id = ConfigHandler.entityId + 1;
|
||||
ConfigHandler.entities.put(name, id);
|
||||
ConfigHandler.entitiesReversed.put(id, name);
|
||||
ConfigHandler.entityId = id;
|
||||
}
|
||||
// Queued outside the monitor so it is never held while the queue lock is taken
|
||||
Queue.queueEntityInsert(id, name);
|
||||
}
|
||||
|
||||
return id;
|
||||
|
||||
@@ -48,18 +48,26 @@ public class MaterialUtils extends Queue {
|
||||
id = ConfigHandler.materials.get(name);
|
||||
}
|
||||
else if (internal) {
|
||||
// Same monitor as reloadAndGetId, so two threads cannot allocate the same id
|
||||
synchronized (ConfigHandler.class) {
|
||||
Integer existing = ConfigHandler.materials.get(name);
|
||||
if (existing != null) {
|
||||
return existing;
|
||||
}
|
||||
|
||||
// Check if another server has already added this material (multi-server setup)
|
||||
id = ConfigHandler.reloadAndGetId(ConfigHandler.CacheType.MATERIALS, name);
|
||||
if (id != -1) {
|
||||
return id;
|
||||
}
|
||||
|
||||
int mid = ConfigHandler.materialId + 1;
|
||||
ConfigHandler.materials.put(name, mid);
|
||||
ConfigHandler.materialsReversed.put(mid, name);
|
||||
ConfigHandler.materialId = mid;
|
||||
Queue.queueMaterialInsert(mid, name);
|
||||
id = ConfigHandler.materials.get(name);
|
||||
id = ConfigHandler.materialId + 1;
|
||||
ConfigHandler.materials.put(name, id);
|
||||
ConfigHandler.materialsReversed.put(id, name);
|
||||
ConfigHandler.materialId = id;
|
||||
}
|
||||
// Queued outside the monitor so it is never held while the queue lock is taken
|
||||
Queue.queueMaterialInsert(id, name);
|
||||
}
|
||||
|
||||
return id;
|
||||
@@ -76,18 +84,26 @@ public class MaterialUtils extends Queue {
|
||||
id = ConfigHandler.blockdata.get(data);
|
||||
}
|
||||
else if (internal) {
|
||||
// Same monitor as reloadAndGetId, so two threads cannot allocate the same id
|
||||
synchronized (ConfigHandler.class) {
|
||||
Integer existing = ConfigHandler.blockdata.get(data);
|
||||
if (existing != null) {
|
||||
return existing;
|
||||
}
|
||||
|
||||
// Check if another server has already added this blockdata (multi-server setup)
|
||||
id = ConfigHandler.reloadAndGetId(ConfigHandler.CacheType.BLOCKDATA, data);
|
||||
if (id != -1) {
|
||||
return id;
|
||||
}
|
||||
|
||||
int bid = ConfigHandler.blockdataId + 1;
|
||||
ConfigHandler.blockdata.put(data, bid);
|
||||
ConfigHandler.blockdataReversed.put(bid, data);
|
||||
ConfigHandler.blockdataId = bid;
|
||||
Queue.queueBlockDataInsert(bid, data);
|
||||
id = ConfigHandler.blockdata.get(data);
|
||||
id = ConfigHandler.blockdataId + 1;
|
||||
ConfigHandler.blockdata.put(data, id);
|
||||
ConfigHandler.blockdataReversed.put(id, data);
|
||||
ConfigHandler.blockdataId = id;
|
||||
}
|
||||
// Queued outside the monitor so it is never held while the queue lock is taken
|
||||
Queue.queueBlockDataInsert(id, data);
|
||||
}
|
||||
|
||||
return id;
|
||||
@@ -189,18 +205,26 @@ public class MaterialUtils extends Queue {
|
||||
id = ConfigHandler.art.get(name);
|
||||
}
|
||||
else if (internal) {
|
||||
// Same monitor as reloadAndGetId, so two threads cannot allocate the same id
|
||||
synchronized (ConfigHandler.class) {
|
||||
Integer existing = ConfigHandler.art.get(name);
|
||||
if (existing != null) {
|
||||
return existing;
|
||||
}
|
||||
|
||||
// Check if another server has already added this art (multi-server setup)
|
||||
id = ConfigHandler.reloadAndGetId(ConfigHandler.CacheType.ART, name);
|
||||
if (id != -1) {
|
||||
return id;
|
||||
}
|
||||
|
||||
int artID = ConfigHandler.artId + 1;
|
||||
ConfigHandler.art.put(name, artID);
|
||||
ConfigHandler.artReversed.put(artID, name);
|
||||
ConfigHandler.artId = artID;
|
||||
Queue.queueArtInsert(artID, name);
|
||||
id = ConfigHandler.art.get(name);
|
||||
id = ConfigHandler.artId + 1;
|
||||
ConfigHandler.art.put(name, id);
|
||||
ConfigHandler.artReversed.put(id, name);
|
||||
ConfigHandler.artId = id;
|
||||
}
|
||||
// Queued outside the monitor so it is never held while the queue lock is taken
|
||||
Queue.queueArtInsert(id, name);
|
||||
}
|
||||
|
||||
return id;
|
||||
|
||||
@@ -18,6 +18,10 @@ public class WorldUtils extends Queue {
|
||||
}
|
||||
int id = -1;
|
||||
try {
|
||||
if (ConfigHandler.worlds.get(name) == null) {
|
||||
int wid = -1;
|
||||
// Same monitor as reloadAndGetId, so two threads cannot allocate the same id
|
||||
synchronized (ConfigHandler.class) {
|
||||
if (ConfigHandler.worlds.get(name) == null) {
|
||||
// Check if another server has already added this world (multi-server setup)
|
||||
id = ConfigHandler.reloadAndGetId(ConfigHandler.CacheType.WORLDS, name);
|
||||
@@ -25,12 +29,17 @@ public class WorldUtils extends Queue {
|
||||
return id;
|
||||
}
|
||||
|
||||
int wid = ConfigHandler.worldId + 1;
|
||||
wid = ConfigHandler.worldId + 1;
|
||||
ConfigHandler.worlds.put(name, wid);
|
||||
ConfigHandler.worldsReversed.put(wid, name);
|
||||
ConfigHandler.worldId = wid;
|
||||
}
|
||||
}
|
||||
// Queued outside the monitor so it is never held while the queue lock is taken
|
||||
if (wid != -1) {
|
||||
Queue.queueWorldInsert(wid, name);
|
||||
}
|
||||
}
|
||||
id = ConfigHandler.worlds.get(name);
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
||||
Reference in new issue
Block a user