Fix for AVATAR_JS-34, Reviewed-by: asquare
This commit is contained in:
parent
1623ac3f40
commit
804927eaa3
@ -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 \
|
||||
|
@ -151,7 +151,6 @@ public final class Server {
|
||||
throw ex;
|
||||
}
|
||||
} finally {
|
||||
eventLoop.timer().clearAll();
|
||||
eventLoop.stop();
|
||||
logging.shutdown();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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<TimerHandle, TimersTask> SCHEDULED = new ConcurrentHashMap<>();
|
||||
private final Map<TimerHandle, Immediate> 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<TimerHandle, TimersTask> 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;
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
@ -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;
|
@ -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;
|
||||
|
101
src/main/js/net/java/avatar/js/timer_wrap.js
Normal file
101
src/main/js/net/java/avatar/js/timer_wrap.js
Normal file
@ -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;
|
||||
|
||||
});
|
@ -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;
|
||||
|
||||
});
|
Loading…
Reference in New Issue
Block a user