[libbluray-devel] Close Xlet sockets when it is terminated
hpi1
git at videolan.org
Wed Oct 29 14:00:41 CET 2014
libbluray | branch: master | hpi1 <hpi1 at anonymous.org> | Wed Oct 29 14:51:15 2014 +0200| [6bfd1d1141a5a53339ec26705ae63eaeb7ff4d8f] | committer: hpi1
Close Xlet sockets when it is terminated
> http://git.videolan.org/gitweb.cgi/libbluray.git/?a=commit;h=6bfd1d1141a5a53339ec26705ae63eaeb7ff4d8f
---
.../bdj/java/org/videolan/BDJAppProxy.java | 1 +
.../bdj/java/org/videolan/BDJSocketFactory.java | 79 +++++++++++++++++
.../bdj/java/org/videolan/BDJSockets.java | 89 ++++++++++++++++++++
.../bdj/java/org/videolan/BDJXletContext.java | 14 +++
src/libbluray/bdj/java/org/videolan/Libbluray.java | 2 +
5 files changed, 185 insertions(+)
diff --git a/src/libbluray/bdj/java/org/videolan/BDJAppProxy.java b/src/libbluray/bdj/java/org/videolan/BDJAppProxy.java
index 5da21b6..ccefb8a 100644
--- a/src/libbluray/bdj/java/org/videolan/BDJAppProxy.java
+++ b/src/libbluray/bdj/java/org/videolan/BDJAppProxy.java
@@ -238,6 +238,7 @@ public class BDJAppProxy implements DVBJProxy, Runnable {
try {
xlet.destroyXlet(force);
+ context.closeSockets();
context.getThreadGroup().waitForShutdown(1000, 1 + context.numEventQueueThreads());
String persistent = System.getProperty("dvb.persistent.root") + File.separator +
diff --git a/src/libbluray/bdj/java/org/videolan/BDJSocketFactory.java b/src/libbluray/bdj/java/org/videolan/BDJSocketFactory.java
new file mode 100644
index 0000000..876a9d9
--- /dev/null
+++ b/src/libbluray/bdj/java/org/videolan/BDJSocketFactory.java
@@ -0,0 +1,79 @@
+/*
+ * This file is part of libbluray
+ * Copyright (C) 2014 Petri Hintukainen <phintuka at users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+package org.videolan;
+
+import java.io.IOException;
+
+import java.lang.reflect.Constructor;
+
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketImpl;
+import java.net.SocketImplFactory;
+
+class BDJSocketFactory implements SocketImplFactory {
+
+ protected static void init() {
+ try {
+ Socket.setSocketImplFactory(new BDJSocketFactory(false));
+ ServerSocket.setSocketFactory(new BDJSocketFactory(true));
+ } catch (IOException e) {
+ logger.error("Failed to hook SocketFactory: " + e);
+ }
+ }
+
+ private BDJSocketFactory(boolean server) {
+ this.server = server;
+ }
+
+ private SocketImpl newSocket() {
+ try {
+ Class defaultSocketImpl = Class.forName("java.net.SocksSocketImpl");
+ Constructor constructor = defaultSocketImpl.getDeclaredConstructor/*s*/(new Class[0])/*[0]*/;
+ constructor.setAccessible(true);
+ return (SocketImpl) constructor.newInstance(new Object[0]);
+ } catch (Exception e) {
+ logger.error("Failed to create socket: " + e + " at " + logger.dumpStack());
+ throw new RuntimeException(e);
+ }
+ }
+
+ public SocketImpl createSocketImpl() {
+
+ if (server) {
+ logger.error("Xlet tried to create server socket");
+ throw new RuntimeException("server sockets disabled");
+ }
+
+ SocketImpl socket = newSocket();
+ BDJXletContext ctx = BDJXletContext.getCurrentContext();
+ if (ctx != null) {
+ logger.info("Xlet " + ctx + " created new socket");
+ ctx.addSocket(socket);
+ } else {
+ logger.error("New socket created outside of Xlet context: " + logger.dumpStack());
+ }
+ return socket;
+ }
+
+ private boolean server = false;
+
+ private static final Logger logger = Logger.getLogger(BDJSocketFactory.class.getName());
+}
diff --git a/src/libbluray/bdj/java/org/videolan/BDJSockets.java b/src/libbluray/bdj/java/org/videolan/BDJSockets.java
new file mode 100644
index 0000000..0395399
--- /dev/null
+++ b/src/libbluray/bdj/java/org/videolan/BDJSockets.java
@@ -0,0 +1,89 @@
+/*
+ * This file is part of libbluray
+ * Copyright (C) 2014 Petri Hintukainen <phintuka at users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+package org.videolan;
+
+import java.lang.reflect.Method;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import java.net.Socket;
+import java.net.SocketImpl;
+
+class BDJSockets {
+
+ protected BDJSockets() {
+ }
+
+ protected synchronized void add(Object obj) {
+ if (!(obj instanceof SocketImpl)) {
+ throw new Error("expected SocketImpl");
+ }
+
+ if (closed) {
+ logger.error("Terminated Xlet tried to create socket at " + logger.dumpStack());
+ throw new Error("Terminated Xlet can not create sockets");
+ }
+
+ /* drop closed sockets */
+ for (Iterator it = sockets.iterator(); it.hasNext(); ) {
+ SocketImpl socketImpl = (SocketImpl)it.next();
+ Socket socket = getSocket(socketImpl);
+ if (socket != null && socket.isClosed()) {
+ it.remove();
+ }
+ }
+
+ sockets.addLast(obj);
+ }
+
+ protected synchronized void closeAll() {
+ closed = true;
+
+ while (!sockets.isEmpty()) {
+ SocketImpl socketImpl = (SocketImpl)sockets.removeFirst();
+ Socket socket = getSocket(socketImpl);
+ if (socket != null && !socket.isClosed()) {
+ logger.warning("Closing " + socket);
+ try {
+ socket.close();
+ } catch (Exception e) {
+ logger.error("Failed to close socket: " + e);
+ }
+ }
+ }
+ }
+
+ private Socket getSocket(SocketImpl socketImpl) {
+ try {
+ Method getSocket = SocketImpl.class.getDeclaredMethod("getSocket", new Class[0]);
+ getSocket.setAccessible(true);
+ return (Socket) getSocket.invoke(socketImpl, new Object[0]);
+ } catch (Exception e) {
+ logger.error("Failed to get Socket: " + e + " at " + logger.dumpStack());
+ return null;
+ }
+ }
+
+ private LinkedList sockets = new LinkedList();
+ private boolean closed = false;
+
+ private static final Logger logger = Logger.getLogger(BDJSockets.class.getName());
+}
diff --git a/src/libbluray/bdj/java/org/videolan/BDJXletContext.java b/src/libbluray/bdj/java/org/videolan/BDJXletContext.java
index d1208f6..65a6281 100644
--- a/src/libbluray/bdj/java/org/videolan/BDJXletContext.java
+++ b/src/libbluray/bdj/java/org/videolan/BDJXletContext.java
@@ -263,6 +263,18 @@ public class BDJXletContext implements javax.tv.xlet.XletContext, javax.microedi
}
/*
+ * sockets
+ */
+
+ protected void addSocket(Object socket) {
+ sockets.add(socket);
+ }
+
+ protected void closeSockets() {
+ sockets.closeAll();
+ }
+
+ /*
* Ixc
*/
@@ -383,6 +395,7 @@ public class BDJXletContext implements javax.tv.xlet.XletContext, javax.microedi
protected void release() {
+ closeSockets();
removeAllFAA();
stopIxcThreads();
defaultLooks.clear();
@@ -424,6 +437,7 @@ public class BDJXletContext implements javax.tv.xlet.XletContext, javax.microedi
private BDJThreadGroup threadGroup = null;
private LinkedList ixcThreads = new LinkedList();
private LinkedList faaList = new LinkedList();
+ private BDJSockets sockets = new BDJSockets();
private HashMap defaultLooks = new HashMap();
private BDJActionQueue callbackQueue;
private static final Logger logger = Logger.getLogger(BDJXletContext.class.getName());
diff --git a/src/libbluray/bdj/java/org/videolan/Libbluray.java b/src/libbluray/bdj/java/org/videolan/Libbluray.java
index 2f1488a..2bb2fa8 100644
--- a/src/libbluray/bdj/java/org/videolan/Libbluray.java
+++ b/src/libbluray/bdj/java/org/videolan/Libbluray.java
@@ -130,6 +130,8 @@ public class Libbluray {
System.setProperty("bluray.memory.font_cache", "4096");
System.setProperty("bluray.network.connected", "YES");
+
+ BDJSocketFactory.init();
}
public static void shutdown() {
More information about the libbluray-devel
mailing list