summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik De Rijcke <Erik.De.Rijcke@prodatamobility.com>2015-03-24 09:33:52 +0100
committerErik De Rijcke <Erik.De.Rijcke@prodatamobility.com>2015-03-24 09:33:52 +0100
commit7fdd00f4eb6205d6dc1be5097e33640b3a3678cb (patch)
tree42e4670ae4cec6c9cd35ad3a84bf36ce1418241a
parent60e1719f672bd34898cdfa2f78a6823978a86c07 (diff)
fix memory leak when adding loop handlers
-rw-r--r--stubs/src/main/java/org/freedesktop/wayland/server/EventLoop.java62
1 files changed, 43 insertions, 19 deletions
diff --git a/stubs/src/main/java/org/freedesktop/wayland/server/EventLoop.java b/stubs/src/main/java/org/freedesktop/wayland/server/EventLoop.java
index d63d2c6..18300fe 100644
--- a/stubs/src/main/java/org/freedesktop/wayland/server/EventLoop.java
+++ b/stubs/src/main/java/org/freedesktop/wayland/server/EventLoop.java
@@ -18,15 +18,19 @@ import org.freedesktop.wayland.HasNative;
import org.freedesktop.wayland.server.jna.*;
import org.freedesktop.wayland.util.ObjectCache;
-import java.awt.*;
-import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
public class EventLoop implements HasNative<Pointer> {
+ //the following three maps are used to implement proper garbage collection in regards to event source and
+ //event callback:
+
+ //This map maps different pointers with same address but separate instance to a single instance.
+ private static final Map<Pointer,Pointer> HANDLER_REF_CACHE = new WeakHashMap<Pointer,Pointer>();
+ //This map maps a single pointer instance to the java object that will be used as handler object.
private static final Map<Pointer, Object> HANDLER_REFS = new WeakHashMap<Pointer, Object>();
- //this map is used to link handler object lifecycle to an event source
+ //this map is used to link handler object lifecycle to an event source lifecycle.
private static final Map<EventSource, Pointer> EVENT_SOURCE_HANDLER_REFS = new WeakHashMap<EventSource, Pointer>();
private static final wl_event_loop_fd_func_t WL_EVENT_LOOP_FD_FUNC = new wl_event_loop_fd_func_t() {
@@ -95,13 +99,27 @@ public class EventLoop implements HasNative<Pointer> {
return eventLoop;
}
+ private Pointer getHandlerRef(Object handler){
+ final Pointer handlerRefKey = Pointer.createConstant(handler.hashCode());
+
+ Pointer handlerRef = HANDLER_REF_CACHE.get(handlerRefKey);
+ if(handlerRef == null){
+ handlerRef = handlerRefKey;
+ HANDLER_REF_CACHE.put(handlerRefKey,handlerRef);
+ }
+ return handlerRef;
+ }
+
public EventSource addFileDescriptor(final int fd,
final int mask,
final FileDescriptorEventHandler handler) {
- final Pointer handlerRef = Pointer.createConstant(handler.hashCode());
- //handler will be garbage collected once event source is collected.
- HANDLER_REFS.put(handlerRef,
- handler);
+ Pointer handlerRef = getHandlerRef(handler);
+ if(!HANDLER_REFS.containsKey(handlerRef)){
+ //handler will be garbage collected once event source is collected.
+ HANDLER_REFS.put(handlerRef,
+ handler);
+ }
+
final EventSource eventSource = EventSource.create(WaylandServerLibrary.INSTANCE()
.wl_event_loop_add_fd(getNative(),
fd,
@@ -114,10 +132,12 @@ public class EventLoop implements HasNative<Pointer> {
}
public EventSource addTimer(final TimerEventHandler handler) {
- final Pointer handlerRef = Pointer.createConstant(handler.hashCode());
- //handler will be garbage collected once event source is collected.
- HANDLER_REFS.put(handlerRef,
- handler);
+ Pointer handlerRef = getHandlerRef(handler);
+ if(!HANDLER_REFS.containsKey(handlerRef)){
+ //handler will be garbage collected once event source is collected.
+ HANDLER_REFS.put(handlerRef,
+ handler);
+ }
final EventSource eventSource = EventSource.create(WaylandServerLibrary.INSTANCE()
.wl_event_loop_add_timer(getNative(),
WL_EVENT_LOOP_TIMER_FUNC,
@@ -129,10 +149,12 @@ public class EventLoop implements HasNative<Pointer> {
public EventSource addSignal(final int signalNumber,
final SignalEventHandler handler) {
- final Pointer handlerRef = Pointer.createConstant(handler.hashCode());
- //handler will be garbage collected once event source is collected.
- HANDLER_REFS.put(handlerRef,
- handler);
+ Pointer handlerRef = getHandlerRef(handler);
+ if(!HANDLER_REFS.containsKey(handlerRef)){
+ //handler will be garbage collected once event source is collected.
+ HANDLER_REFS.put(handlerRef,
+ handler);
+ }
final EventSource eventSource = EventSource.create(WaylandServerLibrary.INSTANCE()
.wl_event_loop_add_signal(getNative(),
signalNumber,
@@ -144,10 +166,12 @@ public class EventLoop implements HasNative<Pointer> {
}
public EventSource addIdle(final IdleHandler handler) {
- final Pointer handlerRef = Pointer.createConstant(handler.hashCode());
- //handler will be garbage collected once event source is collected.
- HANDLER_REFS.put(handlerRef,
- handler);
+ Pointer handlerRef = getHandlerRef(handler);
+ if(!HANDLER_REFS.containsKey(handlerRef)){
+ //handler will be garbage collected once event source is collected.
+ HANDLER_REFS.put(handlerRef,
+ handler);
+ }
final EventSource eventSource = EventSource.create(WaylandServerLibrary.INSTANCE()
.wl_event_loop_add_idle(getNative(),
WL_EVENT_LOOP_IDLE_FUNC,