Mercurial Hosting > luan
diff src/luan/modules/ThreadLuan.java @ 1401:ef1620aa99cb
fix gc issues
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Mon, 16 Sep 2019 22:51:41 -0400 |
parents | eb8b35dccd99 |
children | 27efb1fcbcb5 |
line wrap: on
line diff
--- a/src/luan/modules/ThreadLuan.java Fri Sep 13 05:05:51 2019 -0600 +++ b/src/luan/modules/ThreadLuan.java Mon Sep 16 22:51:41 2019 -0400 @@ -6,11 +6,14 @@ 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; @@ -21,9 +24,13 @@ import luan.LuanException; import luan.LuanCloner; import luan.LuanCloneable; +import luan.lib.logging.Logger; +import luan.lib.logging.LoggerFactory; public final class ThreadLuan { + private static final Logger logger = LoggerFactory.getLogger(ThreadLuan.class); + private static final Executor exec = Executors.newCachedThreadPool(); public static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); @@ -45,6 +52,8 @@ exec.execute(runnable(newFn)); } + private static Map<String,Reference<ScheduledFuture>> scheduleds = new ConcurrentHashMap<String,Reference<ScheduledFuture>>(); + public static void schedule(LuanFunction fn,LuanTable options) throws LuanException { @@ -52,12 +61,19 @@ Number delay = Utils.removeNumber(map,"delay"); Number repeatingDelay = Utils.removeNumber(map,"repeating_delay"); Number repeatingRate = Utils.removeNumber(map,"repeating_rate"); - boolean daemon = Boolean.TRUE.equals(Utils.removeBoolean(map,"daemon")); - final boolean runOnClose = Boolean.TRUE.equals(Utils.removeBoolean(map,"run_on_close")); + String id = Utils.removeString(map,"id"); if( repeatingDelay!=null && repeatingRate!=null ) throw new LuanException("can't define both repeating_delay and repeating_rate"); boolean repeating = repeatingDelay!=null || repeatingRate!=null; Utils.checkEmpty(map); + if( id != null ) { + Reference<ScheduledFuture> ref = scheduleds.remove(id); + if( ref != null ) { + ScheduledFuture sf = ref.get(); + if( sf != null ) + sf.cancel(false); + } + } Luan luan = fn.luan(); LuanCloner cloner = new LuanCloner(LuanCloner.Type.COMPLETE); final Luan newLuan = (Luan)cloner.clone(luan); @@ -74,26 +90,18 @@ sf = scheduler.scheduleWithFixedDelay(r,delay.longValue(),repeatingRate.longValue(),TimeUnit.MILLISECONDS); } else if( delay != null ) { sf = scheduler.schedule(r,delay.longValue(),TimeUnit.MILLISECONDS); - } else if( runOnClose ) { - Closeable c = new Closeable(){public void close(){ - scheduler.schedule(r,0L,TimeUnit.MILLISECONDS); - }}; - luan.registry().put(c,c); // prevent gc - luan.onClose(c); - return; } else { scheduler.schedule(r,0L,TimeUnit.MILLISECONDS); return; } - Closeable c = new Closeable(){public void close(){ - boolean b = sf.cancel(false); - if( runOnClose ) - scheduler.schedule(r,0L,TimeUnit.MILLISECONDS); - }}; - if( !daemon ) - newLuan.registry().put(luan,luan); // prevent gc - luan.registry().put(c,c); // prevent gc - luan.onClose(c); + Object c = new Object() { + protected void finalize() throws Throwable { + sf.cancel(false); + } + }; + luan.registry().put(c,c); // cancel on gc + if( id != null ) + scheduleds.put(id,new WeakReference<ScheduledFuture>(sf)); } /*