diff --git a/event-loop/src/main/java/mc/core/events/EventPipeline.java b/event-loop/src/main/java/mc/core/events/EventPipelineTask.java similarity index 83% rename from event-loop/src/main/java/mc/core/events/EventPipeline.java rename to event-loop/src/main/java/mc/core/events/EventPipelineTask.java index e3a2910..f8303c1 100644 --- a/event-loop/src/main/java/mc/core/events/EventPipeline.java +++ b/event-loop/src/main/java/mc/core/events/EventPipelineTask.java @@ -9,12 +9,14 @@ import mc.core.events.runner.EventExecutorService; import mc.core.events.runner.ResourceRunnable; import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; import java.util.List; +import java.util.concurrent.locks.Lock; @RequiredArgsConstructor @Getter @Slf4j -public class EventPipeline { +public class EventPipelineTask { private final List handlers; private final FullAsyncEventLoop manager; private final Event event; @@ -39,6 +41,11 @@ public class EventPipeline { RegisteredEventHandler handler = handlers.get(currentIndex); if (!event.isCanceled() || !handler.isIgnoreCancelled()) { + List locks = new ArrayList<>(); + + if (handler.isPluginSynchronize()) + locks.add(manager.getResourceManager().getPluginLock(handler.getPlugin())); + service.addTask(new ResourceRunnable() { @Override public void run() { @@ -54,6 +61,11 @@ public class EventPipeline { currentIndex++; next(service); } + + @Override + public List getLocks() { + return locks; + } }); } else { currentIndex++; diff --git a/event-loop/src/main/java/mc/core/events/FullAsyncEventLoop.java b/event-loop/src/main/java/mc/core/events/FullAsyncEventLoop.java index 2b8db05..89e6281 100644 --- a/event-loop/src/main/java/mc/core/events/FullAsyncEventLoop.java +++ b/event-loop/src/main/java/mc/core/events/FullAsyncEventLoop.java @@ -17,10 +17,11 @@ import java.util.concurrent.ConcurrentHashMap; public class FullAsyncEventLoop { Map, List> handlers = new HashMap<>(); // Item leaves this queue only when EventPipeline is fully executed - private Map> eventQueue = new ConcurrentHashMap<>(); + private Map> eventQueue = new ConcurrentHashMap<>(); @Autowired @Setter private EventExecutorService eventExecutorService; + private SharedResourceManager resourceManager = new SharedResourceManager(); public void addEventHandler(Plugin plugin, Object object) { Map candidates = getEventHandlerCandidates(object); @@ -73,8 +74,8 @@ public class FullAsyncEventLoop { if (handlers == null) return; - Queue queue = eventQueue.computeIfAbsent(owner, s -> new ArrayDeque<>()); - queue.add(new EventPipeline(handlers, this, event, owner)); + Queue queue = eventQueue.computeIfAbsent(owner, s -> new ArrayDeque<>()); + queue.add(new EventPipelineTask(handlers, this, event, owner)); update(owner); } @@ -91,22 +92,24 @@ public class FullAsyncEventLoop { log.warn("Unable to update pipeline executor: unable to find queue"); return; } - Queue queue = eventQueue.get(owner); + Queue queue = eventQueue.get(owner); if (queue.isEmpty()) { log.warn("Unable to update pipeline executor: queue is empty"); return; } - if (queue.peek().getState() == EventPipeline.PipelineState.FINISHED) { + if (queue.peek().getState() == EventPipelineTask.PipelineState.FINISHED) { queue.poll(); } - EventPipeline pipeline; + EventPipelineTask pipeline; if ((pipeline = queue.peek()) != null - && pipeline.getState() == EventPipeline.PipelineState.IDLE) { + && pipeline.getState() == EventPipelineTask.PipelineState.IDLE) { pipeline.next(eventExecutorService); } } - + public SharedResourceManager getResourceManager() { + return resourceManager; + } } diff --git a/event-loop/src/main/java/mc/core/events/SharedResourceManager.java b/event-loop/src/main/java/mc/core/events/SharedResourceManager.java new file mode 100644 index 0000000..12f6812 --- /dev/null +++ b/event-loop/src/main/java/mc/core/events/SharedResourceManager.java @@ -0,0 +1,17 @@ +package mc.core.events; + +import mc.core.events.api.Plugin; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +public class SharedResourceManager { + private Map pluginLocks = new ConcurrentHashMap<>(); + + public Lock getPluginLock(Plugin plugin) { + return pluginLocks.computeIfAbsent(plugin, s -> new ReentrantLock()); + } + +}