Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
Bundle-Vendor: %Bundle-Vendor
Bundle-SymbolicName: org.eclipse.e4.core.di.extensions.supplier
Bundle-Version: 0.17.1200.qualifier
Bundle-Version: 0.17.1300.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-17
Require-Capability: osgi.extender;
filter:="(&(osgi.extender=osgi.component)(version>=1.3)(!(version>=2.0)))"
Expand All @@ -19,7 +19,7 @@ Import-Package: jakarta.annotation;version="[2.0.0,4.0.0)",
org.osgi.service.log;version="[1.4.0,2)",
org.osgi.util.tracker;version="[1.5.3,2.0.0)"
Bundle-ActivationPolicy: lazy
Export-Package: org.eclipse.e4.core.di.internal.extensions;version="0.15.0";x-friends:="org.eclipse.e4.ui.di",
Export-Package: org.eclipse.e4.core.di.internal.extensions;version="0.15.0";x-friends:="org.eclipse.e4.ui.di,org.eclipse.e4.core.tests",
org.eclipse.e4.core.di.internal.extensions.util;version="0.15.0";x-internal:=true
Automatic-Module-Name: org.eclipse.e4.core.di.extensions.supplier
Service-Component: OSGI-INF/org.eclipse.e4.core.di.internal.extensions.EventObjectSupplier.xml,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2010, 2017 IBM Corporation and others.
* Copyright (c) 2010, 2026 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
Expand All @@ -19,7 +19,9 @@
import jakarta.annotation.PreDestroy;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Deque;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
Expand Down Expand Up @@ -66,7 +68,19 @@ public void setEventAdmin(EventAdmin eventAdmin) {
this.eventAdmin = eventAdmin;
}

protected Map<String, Event> currentEvents = new HashMap<>();
/**
* The events currently being dispatched, per thread and topic.
* <p>
* Events may be dispatched concurrently by several threads (and even
* re-entrantly on the same thread if an event handler sends another event).
* Since the event is published here only to be picked up by
* {@link #get(IObjectDescriptor, IRequestor, boolean, boolean)} while the
* arguments of the requestor are resolved - which happens on the very same
* thread - the events are tracked per thread. A stack is used per topic to
* support nested dispatching of the same topic.
* </p>
*/
private final ThreadLocal<Map<String, Deque<Event>>> currentEvents = new ThreadLocal<>();
Comment thread
iloveeclipse marked this conversation as resolved.

class DIEventHandler implements EventHandler {

Expand All @@ -86,8 +100,11 @@ public void handleEvent(Event event) {
}

addCurrentEvent(topic, event);
requestor.resolveArguments(false);
removeCurrentEvent(topic);
try {
requestor.resolveArguments(false);
} finally {
removeCurrentEvent(topic);
Comment thread
iloveeclipse marked this conversation as resolved.
}

requestor.execute();
}
Expand Down Expand Up @@ -136,15 +153,40 @@ public boolean equals(Object obj) {
private final Map<Subscriber, ServiceRegistration<EventHandler>> registrations = new HashMap<>();

protected void addCurrentEvent(String topic, Event event) {
synchronized (currentEvents) {
currentEvents.put(topic, event);
Map<String, Deque<Event>> events = currentEvents.get();
if (events == null) {
events = new HashMap<>(2);
currentEvents.set(events);
}
// the stack grows at the head: the innermost delivery is the current one
events.computeIfAbsent(topic, key -> new ArrayDeque<>(1)).addFirst(event);
}

protected void removeCurrentEvent(String topic) {
synchronized (currentEvents) {
currentEvents.remove(topic);
Map<String, Deque<Event>> events = currentEvents.get();
if (events == null) {
return;
}
Deque<Event> stack = events.get(topic);
if (stack != null) {
stack.pollFirst();
if (stack.isEmpty()) {
events.remove(topic);
}
}
if (events.isEmpty()) {
// don't hold on to the map, this thread may not dispatch events again
currentEvents.remove();
}
}

private Event getCurrentEvent(String topic) {
Map<String, Deque<Event>> events = currentEvents.get();
if (events == null) {
return null;
}
Deque<Event> stack = events.get(topic);
return stack == null ? null : stack.peekFirst();
}

@Override
Expand All @@ -163,17 +205,18 @@ public Object get(IObjectDescriptor descriptor, IRequestor requestor, boolean tr
unsubscribe(requestor);
}

if (!currentEvents.containsKey(topic)) {
Event currentEvent = getCurrentEvent(topic);
if (currentEvent == null) {
return IInjector.NOT_A_VALUE;
}

// convert to fit destination
Class<?> descriptorsClass = getDesiredClass(descriptor.getDesiredType());
if (descriptorsClass.equals(Event.class)) {
return currentEvents.get(topic);
if (Event.class.equals(descriptorsClass)) {
return currentEvent;
}

return currentEvents.get(topic).getProperty(DATA);
return currentEvent.getProperty(DATA);
}

private void subscribe(String topic, IRequestor requestor) {
Expand Down Expand Up @@ -211,7 +254,7 @@ protected String getTopic(IObjectDescriptor descriptor) {
return null;
}
EventTopic qualifier = descriptor.getQualifier(EventTopic.class);
return qualifier.value();
return qualifier == null ? null : qualifier.value();
}

protected void unsubscribe(IRequestor requestor) {
Expand Down
Loading
Loading