From 804927eaa3822828c512883cb5a669468eff601c Mon Sep 17 00:00:00 2001 From: jfdenise Date: Thu, 24 Oct 2013 14:11:41 +0200 Subject: [PATCH] Fix for AVATAR_JS-34, Reviewed-by: asquare --- project.properties | 2 + src/main/java/net/java/avatar/js/Server.java | 1 - .../java/avatar/js/eventloop/EventLoop.java | 26 +-- .../net/java/avatar/js/timers/Timers.java | 178 ------------------ .../net/java/avatar/js/timers/TimersTask.java | 122 ------------ src/main/js/lib/process.js | 39 ++++ src/main/js/lib/timers.js | 75 -------- src/main/js/net/java/avatar/js/init.js | 127 +++---------- src/main/js/net/java/avatar/js/timer_wrap.js | 101 ++++++++++ src/main/js/net/java/avatar/js/timers_wrap.js | 56 ------ 10 files changed, 180 insertions(+), 547 deletions(-) delete mode 100644 src/main/java/net/java/avatar/js/timers/Timers.java delete mode 100644 src/main/java/net/java/avatar/js/timers/TimersTask.java delete mode 100644 src/main/js/lib/timers.js create mode 100644 src/main/js/net/java/avatar/js/timer_wrap.js delete mode 100644 src/main/js/net/java/avatar/js/timers_wrap.js diff --git a/project.properties b/project.properties index 91f79d8..282503c 100644 --- a/project.properties +++ b/project.properties @@ -2,6 +2,7 @@ source.compatible.version = 0.10.18 libuv.compatible.version = 0.10.15 source.lib.modules = \ + _linklist.js \ _stream_duplex.js \ _stream_passthrough.js \ _stream_readable.js \ @@ -28,6 +29,7 @@ source.lib.modules = \ readline.js \ stream.js \ string_decoder.js \ + timers.js \ tls.js \ tty.js \ url.js \ diff --git a/src/main/java/net/java/avatar/js/Server.java b/src/main/java/net/java/avatar/js/Server.java index 3c6a4b9..c32a784 100644 --- a/src/main/java/net/java/avatar/js/Server.java +++ b/src/main/java/net/java/avatar/js/Server.java @@ -151,7 +151,6 @@ public final class Server { throw ex; } } finally { - eventLoop.timer().clearAll(); eventLoop.stop(); logging.shutdown(); } diff --git a/src/main/java/net/java/avatar/js/eventloop/EventLoop.java b/src/main/java/net/java/avatar/js/eventloop/EventLoop.java index 837e84c..9bc2e70 100644 --- a/src/main/java/net/java/avatar/js/eventloop/EventLoop.java +++ b/src/main/java/net/java/avatar/js/eventloop/EventLoop.java @@ -55,13 +55,13 @@ import javax.script.ScriptException; import net.java.avatar.js.dns.DNS; import net.java.avatar.js.log.Logger; import net.java.avatar.js.log.Logging; -import net.java.avatar.js.timers.Timers; import net.java.libuv.Callback; import net.java.libuv.CallbackExceptionHandler; import net.java.libuv.CallbackHandler; import net.java.libuv.CheckCallback; import net.java.libuv.FileCallback; +import net.java.libuv.IdleCallback; import net.java.libuv.LibUV; import net.java.libuv.ProcessCallback; import net.java.libuv.SignalCallback; @@ -94,7 +94,6 @@ public final class EventLoop { private final String version; private final String uvVersion; private final Logging logging; - private final Timers timer; private final DNS dns; private final LoopHandle uvLoop; private final int instanceNumber; @@ -140,7 +139,7 @@ public final class EventLoop { private Thread mainThread = null; private Exception pendingException = null; private volatile boolean closed; - + public static final class Handle implements AutoCloseable { private final AtomicInteger hooks; @@ -199,13 +198,12 @@ public final class EventLoop { hooks.get() != 0 || !maybeIdle.get() || activeTasks.get() != 0 || - timer.isPending() || // LinkedBlockingQueue.isEmpty() is quick but not always accurate // peek first element to make sure the queues are really empty // do this last to avoid unnecessary iteration tasks.peek() != null || eventQueue.peek() != null)) { - + // throw pending exception, if any if (pendingException != null) { final Exception pex = pendingException; @@ -319,7 +317,6 @@ public final class EventLoop { public void release() { hooks.set(0); - timer.clearAll(); tasks.clear(); } @@ -459,7 +456,6 @@ public final class EventLoop { this.version = version; this.uvVersion = uvVersion; this.logging = logging; - this.timer = new Timers(this); this.dns = new DNS(this); this.uvLoop = new LoopHandle(new CallbackExceptionHandler() { @Override @@ -543,8 +539,18 @@ public final class EventLoop { uvLoop.getExceptionHandler().handle(ex); } } - }); + @Override + public void handleIdleCallback(IdleCallback cb, int status) { + maybeIdle.set(false); + try { + cb.call(status); + } catch (Exception ex) { + uvLoop.getExceptionHandler().handle(ex); + } + } + }); + this.instanceNumber = instanceNumber; LibUV.chdir(workDir); @@ -568,10 +574,6 @@ public final class EventLoop { return logging.get(name); } - public Timers timer() { - return timer; - } - public DNS dns() { return dns; } diff --git a/src/main/java/net/java/avatar/js/timers/Timers.java b/src/main/java/net/java/avatar/js/timers/Timers.java deleted file mode 100644 index 9ded933..0000000 --- a/src/main/java/net/java/avatar/js/timers/Timers.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package net.java.avatar.js.timers; - -import net.java.libuv.Callback; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.atomic.AtomicInteger; - -import net.java.avatar.js.eventloop.DaemonThreadFactory; -import net.java.avatar.js.eventloop.Event; -import net.java.avatar.js.eventloop.EventLoop; - -public final class Timers { - - public final class TimerHandle { - - final int id; - int referenceCount; - - TimerHandle(final int id) { - this.id = id; - this.referenceCount = 1; - } - - @Override - public int hashCode() { - return id; - } - - @Override - public boolean equals(final Object other) { - if (other instanceof TimerHandle) { - final TimerHandle timerHandle = (TimerHandle) other; - return id == timerHandle.id; - } - return false; - } - - @Override - public String toString() { - return "{name:" + TimerHandle.class.getSimpleName() + - ", id:" + Integer.toString(id) + - ", ref:" + Integer.toString(referenceCount) + "}"; - } - - public void ref() { - referenceCount++; - } - - public TimerHandle unref() { - referenceCount--; - return this; - } - - public boolean isReferenced() { - return referenceCount > 0; - } - } - - final class Immediate implements Callback { - - private final Callback cb; - private boolean cleared; - - Immediate(final Callback cb) { - this.cb = cb; - } - - void clear() { - cleared = true; - } - - @Override - public void call(String name, Object[] args) throws Exception { - if (!cleared) { - cb.call(name, args); - } - } - } - - private final EventLoop eventLoop; - private final AtomicInteger NEXT_ID = new AtomicInteger(); - private final Map SCHEDULED = new ConcurrentHashMap<>(); - private final Map IMMEDIATE = new ConcurrentHashMap<>(); - private final ScheduledExecutorService TIMER = - Executors.newSingleThreadScheduledExecutor(new DaemonThreadFactory("avatar-js.timer")); - - public Timers(final EventLoop eventLoop) { - this.eventLoop = eventLoop; - } - - public TimerHandle setTimeout(final boolean repeating, - final long delay, - final Callback callback) { - // adjust zero or negative (invalid) delay values to the smallest positive delay - final long positiveDelay = delay > 0 ? delay : 1; - final TimerHandle id = new TimerHandle(NEXT_ID.incrementAndGet()); - final TimersTask task = new TimersTask(this, eventLoop, id, positiveDelay, repeating, callback); - SCHEDULED.put(id, task); - return id; - } - - public void start(final TimerHandle id) { - final TimersTask task = SCHEDULED.get(id); - if (task != null) { - task.start(); - } - } - - public void clearTimeout(final TimerHandle timeoutId) { - final TimersTask task = SCHEDULED.remove(timeoutId); - if (task != null) { - task.cancel(); - } - } - - public void clearAll() { - for (final TimersTask task : SCHEDULED.values()) { - task.cancel(); - } - SCHEDULED.clear(); - } - - public boolean isPending() { - for (final Map.Entry entry : SCHEDULED.entrySet()) { - if (entry.getKey().isReferenced()) { - return true; - } - } - return false; - } - - public TimerHandle setImmediate(final Callback callback) { - final Immediate immediate = new Immediate(callback); - final TimerHandle id = new TimerHandle(NEXT_ID.incrementAndGet()); - IMMEDIATE.put(id, immediate); - eventLoop.post(new Event("timer.immediate." + id, immediate)); - return id; - } - - public void clearImmediate(final TimerHandle immediateId) { - final Immediate task = IMMEDIATE.remove(immediateId); - if (task != null) { - task.clear(); - } - } - - ScheduledExecutorService timer() { - return TIMER; - } -} diff --git a/src/main/java/net/java/avatar/js/timers/TimersTask.java b/src/main/java/net/java/avatar/js/timers/TimersTask.java deleted file mode 100644 index 7f9824e..0000000 --- a/src/main/java/net/java/avatar/js/timers/TimersTask.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package net.java.avatar.js.timers; - -import net.java.libuv.Callback; - -import java.util.TimerTask; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -import net.java.avatar.js.eventloop.Event; -import net.java.avatar.js.eventloop.EventLoop; - -final class TimersTask extends TimerTask { - - private final Timers timers; - private final EventLoop eventLoop; - private final long delay; - private final boolean repeating; - private final Callback callback; - private final Timers.TimerHandle id; - private final AtomicBoolean done = new AtomicBoolean(false); - - private ScheduledFuture future = null; - - TimersTask(final Timers timers, - final EventLoop eventLoop, - final Timers.TimerHandle id, - final long delay, - final boolean repeating, - final Callback callback) { - this.timers = timers; - this.eventLoop = eventLoop; - this.delay = delay; - this.repeating = repeating; - this.callback = callback; - this.id = id; - } - - void start() { - future = repeating ? - timers.timer().scheduleAtFixedRate(this, delay, delay, TimeUnit.MILLISECONDS) : - timers.timer().schedule(this, delay, TimeUnit.MILLISECONDS); - } - - @Override - public void run() { - if (!repeating) { - if (done.getAndSet(true)) { - return; - } - // Need to post before to clear, otherwise EvtLoop can exit - // after the timer has been removed. - postEvent(); - timers.clearTimeout(id); - } else { - postEvent(); - } - - } - - private void postEvent() { - final Callback guard = new Callback() { - - @Override - public void call(String name, Object[] args) throws Exception { - if (repeating && done.get()) { - //Already cleared. - return; - } - callback.call(name, args); - } - }; - eventLoop.post(new Event("timer"+id, guard)); - } - - @Override - public boolean equals(final Object obj) { - if (obj instanceof TimersTask) { - return id == ((TimersTask) obj).id; - } - return false; - } - - @Override - public int hashCode() { - return this.id.id; - } - - @Override - public boolean cancel() { - done.set(true); - if (future != null) { - future.cancel(true); - } - return super.cancel(); - } -} diff --git a/src/main/js/lib/process.js b/src/main/js/lib/process.js index bedb40e..677c77c 100644 --- a/src/main/js/lib/process.js +++ b/src/main/js/lib/process.js @@ -563,6 +563,45 @@ exports.openStdin = function() { return process.stdin; } +var Check = Packages.net.java.libuv.handles.CheckHandle; +var Idle = Packages.net.java.libuv.handles.IdleHandle; +var checkHandle = new Check(eventloop.loop()); +checkHandle.setCheckCallback(checkImmediate); +// this handle should not keep the event loop from terminating +checkHandle.unref(); + +// During the lifetime of an immediate callback, we want to keep the loop running. +// This is why an Idle is started/stopped when the unrefed Check is started/stopped +// Nodejs core.cc +var idleHandle = new Idle(eventloop.loop()); +idleHandle.setIdleCallback(IdleImmediateDummy); + +function checkImmediate() { + // This needs to be treated as a callback, all ticked events need to be handled. + if (exports._immediateCallback) { + exports._immediateCallback(); + } +} + +function IdleImmediateDummy() { + // Just to keep the loop running. +} + +Object.defineProperty(exports, '_needImmediateCallback', { + enumerable : true, + set : function(need) { + if (checkHandle) { + if (need) { + checkHandle.start(); + idleHandle.start(); + } else { + checkHandle.stop(); + idleHandle.stop(); + } + } + } +}); + var signalHandle = new Signals(eventloop.loop()); // this handle should not keep the event loop from terminating signalHandle.unref(); diff --git a/src/main/js/lib/timers.js b/src/main/js/lib/timers.js deleted file mode 100644 index b48cab8..0000000 --- a/src/main/js/lib/timers.js +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -// Simple re-export of globals - -exports.setTimeout = setTimeout; - -exports.setInterval = setInterval; - -exports.clearTimeout = clearTimeout; - -exports.clearInterval = clearInterval; - -exports.setImmediate = setImmediate; - -exports.clearImmediate = clearImmediate; - -function enroll(item, delay, repeat) { - var that = item; - unenroll(item); - item._timerId = setTimeout(function() { - that._onTimeout(); - }, delay); - item._idleTimeout = delay; - item._enrolled = true; - -} - -exports.enroll = enroll; - -function unenroll(item) { - if (item._timerId) { - clearTimeout(item._timerId); - item._enrolled = false; - item._idleTimeout = -1; - } -} - -exports.unenroll = unenroll; - -function _unrefActive(item) { - var msecs = item._idleTimeout; - if (msecs >= 0 && !item._enrolled) { - clearTimeout(item._timerId); - var that = item; - item._timerId = setTimeout(function() { - that._onTimeout(); - }, msecs); - item._idleTimeout = msecs; - } -} - -exports._unrefActive = _unrefActive; diff --git a/src/main/js/net/java/avatar/js/init.js b/src/main/js/net/java/avatar/js/init.js index da174ae..0e0a3a3 100644 --- a/src/main/js/net/java/avatar/js/init.js +++ b/src/main/js/net/java/avatar/js/init.js @@ -158,115 +158,36 @@ var gc = global.gc; global.Buffer = Buffer; - // timer functions - var timer = __avatar.eventloop.timer(); - - var _setTimeout = function() { - var repeated = arguments[0]; - var callargs = arguments[1]; - - var len = callargs.length; - if (len < 1) { - throw new Error('timer callback not specified'); - } - var after = callargs[1]; - if (len < 2) { - after = 1; // default to 1ms if not specified - } - - var callback = callargs[0]; - if (typeof callback !== 'function') { - throw new Error('timer callback is not a function (' + (typeof callback) + ')'); - } - - after *= 1; // coalesce to number or NaN - if (!(after >= 1 && after <= java.lang.Integer.MAX_VALUE)) { - after = 1; - } - - var callbackargs = []; - for (var i = 2; i < len; i++) { - callbackargs.push(callargs[i]); - } - var id = timer.setTimeout(repeated, after, function(name, args) { - callback.apply(id, callbackargs); - }); - // defer starting the timer until the next tick - process.nextTick(function() { - timer.start(id); - }); - return id; + global.setTimeout = function() { + var t = NativeModule.require('timers'); + return t.setTimeout.apply(this, arguments); }; - Object.defineProperty(global, 'setTimeout', { - enumerable : true, - value : function() { - return _setTimeout(false, arguments); - } - }); + global.setInterval = function() { + var t = NativeModule.require('timers'); + return t.setInterval.apply(this, arguments); + }; - Object.defineProperty(global, 'clearTimeout', { - enumerable : true, - value : function() { - if (arguments.length > 0) { - if (arguments[0]) { - timer.clearTimeout(arguments[0]); - } - } else { - timer.clearAll(); - } - } - }); + global.clearTimeout = function() { + var t = NativeModule.require('timers'); + return t.clearTimeout.apply(this, arguments); + }; - Object.defineProperty(global, 'setInterval', { - enumerable : true, - value : function() { - return _setTimeout(true, arguments); - } - }); + global.clearInterval = function() { + var t = NativeModule.require('timers'); + return t.clearInterval.apply(this, arguments); + }; - Object.defineProperty(global, 'clearInterval', { - enumerable : true, - value : function() { - if (arguments.length > 0) { - if (arguments[0]) { - timer.clearTimeout(arguments[0]); - } - } else { - timer.clearAll(); - } - } - }); - - Object.defineProperty(global, 'setImmediate', { - enumerable : true, - value : function() { - var cb = arguments[0] - var callbackargs = []; - for (var i = 1; i < arguments.length; i++) { - callbackargs.push(arguments[i]); - } - var ctx = {}; - var wrapper = function() { - cb.apply(ctx, callbackargs); - } - - ctx.id = timer.setImmediate(wrapper); - return ctx; - } - }); - - Object.defineProperty(global, 'clearImmediate', { - enumerable : true, - value : function() { - if (arguments.length > 0) { - if (arguments[0]) { - timer.clearImmediate(arguments[0].id); - } - } - } - }); + global.setImmediate = function() { + var t = NativeModule.require('timers'); + return t.setImmediate.apply(this, arguments); + }; + global.clearImmediate = function() { + var t = NativeModule.require('timers'); + return t.clearImmediate.apply(this, arguments); + }; + // console require timers that require setTimeout. var console = NativeModule.require('console'); global.console = console; diff --git a/src/main/js/net/java/avatar/js/timer_wrap.js b/src/main/js/net/java/avatar/js/timer_wrap.js new file mode 100644 index 0000000..afc085b --- /dev/null +++ b/src/main/js/net/java/avatar/js/timer_wrap.js @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +(function(exports) { + var TimerHandle = Packages.net.java.libuv.handles.TimerHandle; + var loop = __avatar.eventloop.loop(); + + function Timer() { + Object.defineProperty(this, '_timer', { value: new TimerHandle(loop) }); + var that = this; + this._timer.setTimerFiredCallback(function(status) { + if (that.ontimeout) { + that.ontimeout(); + } + }); + } + + Timer.prototype.start = function(timeout, repeat) { + try { + this._timer.start(timeout, repeat); + } catch(err) { + if (!err.errnoString) { + throw err; + } + process._errno = err.errnoString(); + throw err; + } + } + + Timer.prototype.stop = function() { + try { + this._timer.stop(); + } catch(err) { + if (!err.errnoString) { + throw err; + } + process._errno = err.errnoString(); + throw err; + } + } + + Timer.prototype.again = function() { + try { + this._timer.again(); + } catch(err) { + if (!err.errnoString) { + throw err; + } + process._errno = err.errnoString(); + throw err; + } + } + + Timer.prototype.setRepeat = function(repeat) { + this._timer.setRepeat(repeat); + } + + Timer.prototype.getRepeat = function() { + return this._timer.getRepeat(); + } + + Timer.prototype.ref = function() { + this._timer.ref(); + } + + Timer.prototype.unref = function() { + this._timer.unref(); + } + + Timer.prototype.close = function() { + if (!this.closed) { + this.closed = true; + this._timer.close(); + } + } + + exports.Timer = Timer; + +}); diff --git a/src/main/js/net/java/avatar/js/timers_wrap.js b/src/main/js/net/java/avatar/js/timers_wrap.js deleted file mode 100644 index 85ee7c0..0000000 --- a/src/main/js/net/java/avatar/js/timers_wrap.js +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -(function(exports) { - - exports.Timer = function() { - return new Timer(); - } - - function Timer() { - this.timer = new Packages.net.java.avatar.js.timers.Timers(__eventloop_instance); - } - - Timer.prototype.start = function(timeout, repeat) { - var that = this; - this.timer.setTimeout(repeat, timeout, function() { - that.ontimeout(); - }) - } - - Timer.prototype.close = function() { - this.timer.clearAll(); - this.timer = undefined; - } - - exports.setTimeout = setTimeout; - - exports.setInterval = setInterval; - - exports.clearTimeout = clearTimeout; - - exports.clearInterval = clearInterval; - -});