From b62d20a86e86379bb7d5c92e49d75c2e00057517 Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Wed, 6 Jul 2011 10:26:04 -0700 Subject: [PATCH] Fixes to Scheduler behavior in the mobile filter framework. - Move reset() out of base Scheduler constructor - Add reset() to start of run - Add reset() to close() - Move pre-run checks around to have null checks before use - Add better exception throwing from invoking Scheduler constructor Change-Id: I673b2cd9fcfa7b4ad70b3296692731ac79bda55f --- .../java/android/filterfw/core/AsyncRunner.java | 11 ++++++++--- .../android/filterfw/core/OneShotScheduler.java | 19 ++++++++++++++++--- .../java/android/filterfw/core/Scheduler.java | 1 - .../java/android/filterfw/core/SyncRunner.java | 21 ++++++++++++++------- 4 files changed, 38 insertions(+), 14 deletions(-) diff --git a/mca/filterfw/java/android/filterfw/core/AsyncRunner.java b/mca/filterfw/java/android/filterfw/core/AsyncRunner.java index 4f4ffd11..bbd43bb4 100644 --- a/mca/filterfw/java/android/filterfw/core/AsyncRunner.java +++ b/mca/filterfw/java/android/filterfw/core/AsyncRunner.java @@ -66,6 +66,8 @@ public class AsyncRunner extends GraphRunner{ throw new RuntimeException("More than one callback data set received!"); } + runner[0].assertReadyToStep(); + // Preparation if (mLogVerbose) Log.v(TAG, "Starting background graph processing."); activateGlContext(); @@ -74,7 +76,6 @@ public class AsyncRunner extends GraphRunner{ runner[0].beginProcessing(); if (mLogVerbose) Log.v(TAG, "Running graph."); - runner[0].assertReadyToStep(); // Run loop int status = RESULT_RUNNING; @@ -91,8 +92,6 @@ public class AsyncRunner extends GraphRunner{ // Cleanup if (isCancelled()) { status = RESULT_STOPPED; - if (mLogVerbose) Log.v(TAG, "Closing filters."); - runner[0].close(); } deactivateGlContext(); @@ -109,6 +108,10 @@ public class AsyncRunner extends GraphRunner{ @Override protected void onPostExecute(Integer result) { if (mLogVerbose) Log.v(TAG, "Starting post-execute."); + if (result == RESULT_STOPPED) { + if (mLogVerbose) Log.v(TAG, "Closing filters."); + mRunner.close(); + } if (mDoneListener != null) { if (mLogVerbose) Log.v(TAG, "Invoking graph done callback."); mDoneListener.onRunnerDone(result); @@ -166,6 +169,7 @@ public class AsyncRunner extends GraphRunner{ public AsyncRunner(FilterContext context) { super(context); mSchedulerClass = SimpleScheduler.class; + mLogVerbose = Log.isLoggable(TAG, Log.VERBOSE); } /** Set a callback to be called in the UI thread once the AsyncRunner @@ -225,6 +229,7 @@ public class AsyncRunner extends GraphRunner{ if (isRunning()) { throw new RuntimeException("Cannot close graph while it is running!"); } + if (mLogVerbose) Log.v(TAG, "Closing filters."); mRunner.close(); } diff --git a/mca/filterfw/java/android/filterfw/core/OneShotScheduler.java b/mca/filterfw/java/android/filterfw/core/OneShotScheduler.java index 3edb61f0..cd0c8ec7 100644 --- a/mca/filterfw/java/android/filterfw/core/OneShotScheduler.java +++ b/mca/filterfw/java/android/filterfw/core/OneShotScheduler.java @@ -20,6 +20,7 @@ package android.filterfw.core; import android.filterfw.core.Filter; import android.filterfw.core.Scheduler; import android.filterfw.core.RoundRobinScheduler; +import android.util.Log; import java.util.HashMap; @@ -28,10 +29,15 @@ import java.util.HashMap; * @hide */ public class OneShotScheduler extends RoundRobinScheduler { - private HashMap scheduled = new HashMap(); + private HashMap scheduled; + + private final boolean mLogVerbose; + private static final String TAG = "OneShotScheduler"; public OneShotScheduler(FilterGraph graph) { super(graph); + scheduled = new HashMap(); + mLogVerbose = Log.isLoggable(TAG, Log.VERBOSE); } @Override @@ -46,16 +52,23 @@ public class OneShotScheduler extends RoundRobinScheduler { // return the first filter that is not scheduled before. while (true) { Filter filter = super.scheduleNextNode(); - if (filter == null) return null; + if (filter == null) { + if (mLogVerbose) Log.v(TAG, "No filters available to run."); + return null; + } if (!scheduled.containsKey(filter.getName())) { scheduled.put(filter.getName(),1); + if (mLogVerbose) Log.v(TAG, "Scheduling filter \"" + filter.getName() + "\" of type " + filter.getFilterClassName()); return filter; } // if loop back, nothing available - if (first == filter) break; + if (first == filter) { + break; + } // save the first scheduled one if (first == null) first = filter; } + if (mLogVerbose) Log.v(TAG, "One pass through graph completed."); return null; } } diff --git a/mca/filterfw/java/android/filterfw/core/Scheduler.java b/mca/filterfw/java/android/filterfw/core/Scheduler.java index a41b4b03..6f0864ab 100644 --- a/mca/filterfw/java/android/filterfw/core/Scheduler.java +++ b/mca/filterfw/java/android/filterfw/core/Scheduler.java @@ -30,7 +30,6 @@ public abstract class Scheduler { Scheduler(FilterGraph graph) { mGraph = graph; - reset(); } FilterGraph getGraph() { diff --git a/mca/filterfw/java/android/filterfw/core/SyncRunner.java b/mca/filterfw/java/android/filterfw/core/SyncRunner.java index 9147a53e..ac7b3564 100644 --- a/mca/filterfw/java/android/filterfw/core/SyncRunner.java +++ b/mca/filterfw/java/android/filterfw/core/SyncRunner.java @@ -21,6 +21,7 @@ import android.os.ConditionVariable; import android.util.Log; import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -54,13 +55,15 @@ public class SyncRunner extends GraphRunner { Constructor schedulerConstructor = schedulerClass.getConstructor(FilterGraph.class); mScheduler = (Scheduler)schedulerConstructor.newInstance(graph); } catch (NoSuchMethodException e) { - throw new RuntimeException("Scheduler does not have constructor (FilterGraph)!"); + throw new RuntimeException("Scheduler does not have constructor (FilterGraph)!", e); } catch (InstantiationException e) { - throw new RuntimeException("Could not instantiate the Scheduler instance!"); + throw new RuntimeException("Could not instantiate the Scheduler instance!", e); } catch (IllegalAccessException e) { - throw new RuntimeException("Cannot access Scheduler constructor!"); + throw new RuntimeException("Cannot access Scheduler constructor!", e); + } catch (InvocationTargetException e) { + throw new RuntimeException("Scheduler constructor threw an exception", e); } catch (Exception e) { - throw new RuntimeException("Could not instantiate Scheduler: " + e.getMessage()); + throw new RuntimeException("Could not instantiate Scheduler", e); } } else { throw new IllegalArgumentException("Class provided is not a Scheduler subclass!"); @@ -90,10 +93,14 @@ public class SyncRunner extends GraphRunner { public int step() { assertReadyToStep(); + if (!getGraph().isReady() ) { + throw new RuntimeException("Trying to process graph that is not open!"); + } return performStep() ? RESULT_RUNNING : determinePostRunState(); } public void beginProcessing() { + mScheduler.reset(); getGraph().beginProcessing(); } @@ -101,15 +108,17 @@ public class SyncRunner extends GraphRunner { // Close filters if (mLogVerbose) Log.v(TAG, "Closing graph."); getGraph().closeFilters(mFilterContext); + mScheduler.reset(); } @Override public void run() { if (mLogVerbose) Log.v(TAG, "Beginning run."); + assertReadyToStep(); + // Preparation beginProcessing(); - assertReadyToStep(); boolean glActivated = activateGlContext(); // Run @@ -213,8 +222,6 @@ public class SyncRunner extends GraphRunner { throw new RuntimeException("Attempting to run schedule with no scheduler in place!"); } else if (getGraph() == null) { throw new RuntimeException("Calling step on scheduler with no graph in place!"); - } else if (!getGraph().isReady() ) { - throw new RuntimeException("Trying to process graph that is not open!"); } } } -- 2.11.0