Mercurial Hosting > luan
diff src/luan/modules/ThreadLuan.java @ 1578:c922446f53aa
immutable threading
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 08 Feb 2021 14:16:19 -0700 |
parents | 8fbcc4747091 |
children | f2a663a4ba9e |
line wrap: on
line diff
--- a/src/luan/modules/ThreadLuan.java Sun Jan 31 16:04:39 2021 -0700 +++ b/src/luan/modules/ThreadLuan.java Mon Feb 08 14:16:19 2021 -0700 @@ -17,8 +17,7 @@ import luan.LuanFunction; import luan.LuanTable; import luan.LuanException; -import luan.LuanCloner; -import luan.LuanCloneable; +import luan.LuanMutable; import luan.modules.logging.LuanLogger; import goodjava.logging.Logger; import goodjava.logging.LoggerFactory; @@ -45,10 +44,9 @@ }; } - public static void fork(Luan luan,LuanFunction fn) { - LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE); - luan = (Luan)cloner.get(luan); - fn = (LuanFunction)cloner.get(fn); + public static void fork(Luan luan,LuanFunction fn) throws LuanException { + luan = new Luan(luan); + LuanMutable.makeImmutable(fn); exec.execute(runnable(luan,fn)); } @@ -60,9 +58,26 @@ logger.error(src+" cancel="+b+" isCancelled="+sf.isCancelled()+" isDone="+sf.isDone()+" "+sf); } + public static synchronized void schedule_closure(Luan luan,LuanFunction initFn,LuanTable options) + throws LuanException + { + final Luan newLuan = new Luan(luan); + LuanMutable.makeImmutable(initFn); + LuanFunction fn = (LuanFunction)initFn.call(newLuan); + scheduleFn(luan,newLuan,fn,options); + } + public static synchronized void schedule(Luan luan,LuanFunction fn,LuanTable options) throws LuanException { + final Luan newLuan = new Luan(luan); + LuanMutable.makeImmutable(fn); + scheduleFn(luan,newLuan,fn,options); + } + + private static synchronized void scheduleFn(Luan luan,final Luan newLuan,LuanFunction fn,LuanTable options) + throws LuanException + { options = new LuanTable(options); Number delay = Utils.removeNumber(options,"delay"); Number repeatingDelay = Utils.removeNumber(options,"repeating_delay"); @@ -77,10 +92,7 @@ if( sf != null ) cancel(sf,"id "+id); } - LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE); - final Luan newLuan = (Luan)cloner.clone(luan); - final LuanFunction newFn = (LuanFunction)cloner.get(fn); - final Runnable r = runnable(newLuan,newFn); + final Runnable r = runnable(newLuan,fn); final ScheduledFuture sf; if( repeatingDelay != null ) { if( delay==null ) @@ -106,104 +118,24 @@ scheduleds.put(id,sf); } -/* - public static class GlobalMap { - - private static class Value { - final long time = System.currentTimeMillis(); - final Object v; - - Value(Object v) { - this.v = v; - } - } - - public long timeout = 60000L; // one minute - private Map<String,Value> map = new LinkedHashMap<String,Value>() { - protected boolean removeEldestEntry(Map.Entry<String,Value> eldest) { - return eldest.getValue().time < System.currentTimeMillis() - timeout; - } - }; - - public synchronized Object get(String key) { - Value val = map.get(key); - return val==null ? null : val.v; - } - - public synchronized Object put(String key,Object v) throws LuanException { - Value val; - if( v == null ) { - val = map.remove(key); - } else { - if( !(v instanceof String || v instanceof Boolean || v instanceof Number) ) - throw new LuanException("can't assign type "+Luan.type(v)+" to Thread.global"); - val = map.put(key,new Value(v)); - } - return val==null ? null : val.v; - } - } -*/ public static void sleep(long millis) throws InterruptedException { Thread.sleep(millis); } - private static class Unsafe { - private final String reason; - - Unsafe(String reason) { - this.reason = reason; - } - } - - private static Object makeSafe(Object v) throws LuanException { - if( v instanceof LuanTable ) { - LuanTable tbl = (LuanTable)v; - if( tbl.getMetatable() != null ) - return new Unsafe("table with metatable"); - LuanTable rtn = new LuanTable(); - for( Map.Entry entry : tbl.rawIterable() ) { - Object key = makeSafe( entry.getKey() ); - if( key instanceof Unsafe ) - return key; - Object value = makeSafe( entry.getValue() ); - if( value instanceof Unsafe ) - return value; - rtn.rawPut(key,value); - } - return rtn; - } else if( v instanceof Object[] ) { - Object[] a = (Object[])v; - for( int i=0; i<a.length; i++ ) { - Object obj = makeSafe(a[i]); - if( obj instanceof Unsafe ) - return obj; - a[i] = obj; - } - return a; - } else { - if( v instanceof LuanCloneable ) - return new Unsafe("type "+Luan.type(v)); - return v; - } - } - public static final class Callable { private long expires; private final Luan luan = new Luan(); private final LuanTable fns; - Callable(LuanTable fns) { - LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE); - this.fns = (LuanTable)cloner.get(fns); + Callable(LuanFunction initFn) throws LuanException { + LuanMutable.makeImmutable(initFn); + this.fns = (LuanTable)initFn.call(luan); } public synchronized Object call(Luan callerLuan,String fnName,Object... args) throws LuanException { - Object obj = makeSafe(args); - if( obj instanceof Unsafe ) - throw new LuanException("can't pass "+((Unsafe)obj).reason+" to global_callable "+Arrays.asList(args)); - args = (Object[])obj; + LuanMutable.makeImmutable(args); Object f = fns.get(luan,fnName); if( f == null ) throw new LuanException("function '"+fnName+"' not found in global_callable"); @@ -211,9 +143,7 @@ throw new LuanException("value of '"+fnName+"' not a function in global_callable"); LuanFunction fn = (LuanFunction)f; Object rtn = fn.call(luan,args); - rtn = makeSafe(rtn); - if( rtn instanceof Unsafe ) - throw new LuanException("can't return "+((Unsafe)rtn).reason+" from global_callable"); + LuanMutable.makeImmutable(rtn); return rtn; } } @@ -229,11 +159,11 @@ } } - public static synchronized Callable globalCallable(String name,LuanTable fns,long timeout) { + public static synchronized Callable globalCallable(String name,LuanFunction initFn,long timeout) throws LuanException { Callable callable = callableMap.get(name); if( callable == null ) { sweep(); - callable = new Callable(fns); + callable = new Callable(initFn); callableMap.put(name,callable); } callable.expires = System.currentTimeMillis() + timeout;