diff src/fschmidt/util/java/ProxyIntoThread.java @ 68:00520880ad02

add fschmidt source
author Franklin Schmidt <fschmidt@gmail.com>
date Sun, 05 Oct 2025 17:24:15 -0600
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/fschmidt/util/java/ProxyIntoThread.java	Sun Oct 05 17:24:15 2025 -0600
@@ -0,0 +1,113 @@
+/*
+Copyright (c) 2008  Franklin Schmidt <fschmidt@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+package fschmidt.util.java;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+
+
+public class ProxyIntoThread<T> extends ProxyClass<T> {
+	private static final Logger logger = LoggerFactory.getLogger(ProxyIntoThread.class);
+	private final long timeout;
+	private volatile Thread thread;
+	private final Object lock = new Object();
+	private boolean isCalling = false;
+	private Method method;
+	private Object[] args;
+	private Object rtn;
+	private Throwable ex;
+
+	public ProxyIntoThread(String threadName,long timeout,final T obj,Class<T> cls) {
+		super(obj,cls);
+		this.timeout = timeout;
+		logger.info("Name = " + threadName + " / timeout = " + timeout + " / isCalling = " + isCalling);
+		thread = new Thread(
+			new Runnable(){public void run(){
+				synchronized(lock) {
+					while(thread!=null) {
+						while( !isCalling ) {
+							try {
+								lock.wait(ProxyIntoThread.this.timeout);
+							} catch(InterruptedException e) {
+								logger.error("",e);
+								throw new RuntimeException(e);
+							}
+							if( !isCalling ) {
+								logger.error("timed out");
+								throw new RuntimeException("timed out");
+							}
+						}
+						try {
+							rtn = invoke(method,args);
+						} catch(Throwable e) {
+							ex = e;
+						} finally {
+							isCalling = false;
+							lock.notifyAll();
+						}
+					}
+				}
+			}}
+			, threadName
+		);
+		thread.start();
+	}
+
+	public Object invoke(Object proxy,Method method,Object[] args)
+		throws Throwable
+	{
+		synchronized(lock) {
+			if( thread==null )
+				throw new RuntimeException("thread died");
+			if( isCalling )
+				throw new RuntimeException("Already calling " + this.method.getName());
+			this.method = method;
+			this.args = args;
+			this.ex = null;
+			isCalling = true;
+			lock.notifyAll();
+			while( isCalling ) {
+				try {
+					lock.wait(timeout);
+				} catch(InterruptedException e) {
+					logger.error("",e);
+					throw new RuntimeException(e);
+				}
+				if( isCalling ) {
+					logger.error("timed out");
+					throw new RuntimeException("timed out");
+				}
+			}
+			if( ex != null )
+				throw ex;
+			return this.rtn;
+		}
+	}
+
+	public void stop() {
+		thread = null;
+	}
+}