add Cron
authoradam <adam@megacz.com>
Sun, 8 Jul 2007 22:52:58 +0000 (22:52 +0000)
committeradam <adam@megacz.com>
Sun, 8 Jul 2007 22:52:58 +0000 (22:52 +0000)
darcs-hash:20070708225258-5007d-d4dc34bde6f5d1cfe5636dbaadabd9fd6ac16899.gz

src/org/ibex/util/Cron.java [new file with mode: 0644]

diff --git a/src/org/ibex/util/Cron.java b/src/org/ibex/util/Cron.java
new file mode 100644 (file)
index 0000000..6dd3688
--- /dev/null
@@ -0,0 +1,69 @@
+// Copyright 2007 the Contributors, as shown in the revision logs.
+// Licensed under the Apache Public Source License 2.0 ("the License").
+// You may not use this file except in compliance with the License.
+
+package org.ibex.util;
+
+import java.io.*;
+
+// FEATURE: auto-rescheduling
+// (currently cronjobs must manually reschedule themselves)
+
+/**
+ *  A manager for periodic tasks ("cron jobs")
+ */
+public final class Cron extends ImmortalThread {
+
+    private static ThreadPool threadPool;
+
+    private Vec tasks = new Vec();
+    private long wakeup = 0;
+
+    public Cron(ThreadPool threadPool) {
+        super(0);
+        this.threadPool = threadPool;
+        start();
+    }
+
+    public synchronized void cycle() {
+        try {
+            long now = System.currentTimeMillis();
+            if (wakeup == 0)       wait();
+            else if (wakeup > now) wait(wakeup - now);
+        } catch (Exception e) { Log.error(this, e); }
+        wakeup = 0;
+        long now = System.currentTimeMillis();
+        // FIXME: linear scan is inefficient
+        for(int i=0; i<tasks.size(); i++) {
+            Task t = (Task)tasks.get(i);
+            if (t.when <= now) {
+                tasks.remove(i--);
+                threadPool.start(t.runnable);
+            } else {
+                if (wakeup == 0 || wakeup > t.when)
+                    wakeup = t.when;
+            }
+        }
+    }
+
+    public void executeLater(long howLongFromNow, Runnable runnable) {
+        new Task(runnable, System.currentTimeMillis()+howLongFromNow);
+    }
+
+    private class Task {
+        final Runnable runnable;
+        final long     when;
+        public Task(Runnable runnable, long when) {
+            this.runnable = runnable;
+            this.when     = when;
+            synchronized(Cron.this) {
+                tasks.add(this);
+                if (wakeup == 0 || wakeup > when) {
+                    wakeup = this.when;
+                    Cron.this.notify();
+                }
+            }
+        }
+    }
+}
+