changeset 1515:78d937870762

Thread.synchronized
author Franklin Schmidt <fschmidt@gmail.com>
date Sat, 30 May 2020 17:58:35 -0600
parents af45ed10aff6
children 70a55f49b98e
files conv.txt src/luan/modules/Thread.luan src/luan/modules/ThreadLuan.java
diffstat 3 files changed, 36 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
diff -r af45ed10aff6 -r 78d937870762 conv.txt
--- a/conv.txt	Tue May 26 22:36:33 2020 -0600
+++ b/conv.txt	Sat May 30 17:58:35 2020 -0600
@@ -1,3 +1,6 @@
+Thread.run_in_lock
+Thread.new_synchronizer
+
 link_to
 
 json_compressed_string
diff -r af45ed10aff6 -r 78d937870762 src/luan/modules/Thread.luan
--- a/src/luan/modules/Thread.luan	Tue May 26 22:36:33 2020 -0600
+++ b/src/luan/modules/Thread.luan	Sat May 30 17:58:35 2020 -0600
@@ -83,14 +83,25 @@
 end
 
 
+local default_time_out = Time.period{minutes=10}
 local run_in_lock = ThreadLuan.runInLock
-Thread.run_in_lock = run_in_lock
+local get_lock = ThreadLuan.getLock
 
+function Thread.synchronized(fn,key,time_out)
+	time_out = time_out or default_time_out
+	local lock = get_lock(key)
+	return function(...)
+		return run_in_lock(lock,time_out,fn,...)
+	end
+end
+
+
+-- remove
 function Thread.new_synchronizer()
 	local lock = ReentrantLock.new()
 	return function(fn)
 		return function(...)
-			return run_in_lock(lock,fn,...)
+			return run_in_lock(lock,default_time_out,fn,...)
 		end
 	end
 end
diff -r af45ed10aff6 -r 78d937870762 src/luan/modules/ThreadLuan.java
--- a/src/luan/modules/ThreadLuan.java	Tue May 26 22:36:33 2020 -0600
+++ b/src/luan/modules/ThreadLuan.java	Sat May 30 17:58:35 2020 -0600
@@ -5,19 +5,14 @@
 import java.util.Iterator;
 import java.util.Map;
 import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.lang.ref.Reference;
-import java.lang.ref.WeakReference;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
+import goodjava.util.WeakCacheMap;
 import luan.Luan;
 import luan.LuanFunction;
 import luan.LuanTable;
@@ -56,7 +51,7 @@
 		exec.execute(runnable(newFn));
 	}
 
-	private static Map<String,Reference<ScheduledFuture>> scheduleds = new ConcurrentHashMap<String,Reference<ScheduledFuture>>();
+	private static final Map<String,ScheduledFuture> scheduleds = new WeakCacheMap<String,ScheduledFuture>();
 
 	private static void cancel(ScheduledFuture sf,String src) {
 		boolean b = sf.cancel(false);
@@ -64,7 +59,7 @@
 			logger.error(src+" cancel="+b+" isCancelled="+sf.isCancelled()+" isDone="+sf.isDone()+" "+sf);
 	}
 
-	public static void schedule(LuanFunction fn,LuanTable options)
+	public static synchronized void schedule(LuanFunction fn,LuanTable options)
 		throws LuanException
 	{
 		options = new LuanTable(options);
@@ -77,12 +72,9 @@
 		boolean repeating = repeatingDelay!=null || repeatingRate!=null;
 		Utils.checkEmpty(options);
 		if( id != null ) {
-			Reference<ScheduledFuture> ref = scheduleds.remove(id);
-			if( ref != null ) {
-				ScheduledFuture sf = ref.get();
-				if( sf != null )
-					cancel(sf,"id "+id);
-			}
+			ScheduledFuture sf = scheduleds.remove(id);
+			if( sf != null )
+				cancel(sf,"id "+id);
 		}
 		Luan luan = fn.luan();
 		LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE);
@@ -111,7 +103,7 @@
 		};
 		luan.registry().put(c,c);  // cancel on gc
 		if( id != null )
-			scheduleds.put(id,new WeakReference<ScheduledFuture>(sf));
+			scheduleds.put(id,sf);
 	}
 
 /*
@@ -253,17 +245,11 @@
 	}
 
 
-	public static void lock(Lock lock)
+	public static Object runInLock(Lock lock,long timeout,LuanFunction fn,Object... args)
 		throws LuanException, InterruptedException
 	{
-		if( !lock.tryLock(10,TimeUnit.MINUTES) )
+		if( !lock.tryLock(timeout,TimeUnit.MILLISECONDS) )
 			throw new LuanException("failed to acquire lock");
-	}
-
-	public static Object runInLock(Lock lock,LuanFunction fn,Object... args)
-		throws LuanException, InterruptedException
-	{
-		lock(lock);
 		try {
 			return fn.call(args);
 		} finally {
@@ -271,4 +257,15 @@
 		}
 	}
 
+	private static final Map<String,Lock> locks = new WeakCacheMap<String,Lock>();
+
+	public static synchronized Lock getLock(String key) {
+		Lock lock = locks.get(key);
+		if( lock == null ) {
+			lock = new ReentrantLock();
+			locks.put(key,lock);
+		}
+		return lock;
+	}
+
 }