Fix for AVATAR_JS-95, support for domains
reviewed-by: asquare
This commit is contained in:
parent
513b1208c7
commit
d00cde3964
@ -285,6 +285,7 @@
|
||||
<apply-diff src="test/simple" mod="${test.dir}/simple" name="test-dgram-ref.js"/>
|
||||
<apply-diff src="test/simple" mod="${test.dir}/simple" name="test-dgram-udp4.js"/>
|
||||
<apply-diff src="test/simple" mod="${test.dir}/simple" name="test-dgram-unref.js"/>
|
||||
<apply-diff src="test/simple" mod="${test.dir}/simple" name="test-domain.js"/>
|
||||
<apply-diff src="test/simple" mod="${test.dir}/simple" name="test-error-reporting.js"/>
|
||||
<apply-diff src="test/simple" mod="${test.dir}/simple" name="test-fs-read-stream.js"/>
|
||||
<apply-diff src="test/simple" mod="${test.dir}/simple" name="test-fs-readfile-pipe.js"/>
|
||||
@ -361,6 +362,7 @@
|
||||
<apply-patch-file target="${test.dir}/simple" dir="test/simple" name="test-dgram-ref.js"/>
|
||||
<apply-patch-file target="${test.dir}/simple" dir="test/simple" name="test-dgram-udp4.js"/>
|
||||
<apply-patch-file target="${test.dir}/simple" dir="test/simple" name="test-dgram-unref.js"/>
|
||||
<apply-patch-file target="${test.dir}/simple" dir="test/simple" name="test-domain.js"/>
|
||||
<apply-patch-file target="${test.dir}/simple" dir="test/simple" name="test-error-reporting.js"/>
|
||||
<apply-patch-file target="${test.dir}/simple" dir="test/simple" name="test-fs-read-stream.js"/>
|
||||
<apply-patch-file target="${test.dir}/simple" dir="test/simple" name="test-fs-readfile-pipe.js"/>
|
||||
|
29
patches/test/simple/test-domain.js.patch
Normal file
29
patches/test/simple/test-domain.js.patch
Normal file
@ -0,0 +1,29 @@
|
||||
--- ../node/test/simple/test-domain.js 2013-08-22 13:48:54.000000000 +0200
|
||||
+++ test/simple/test-domain.js 2013-12-04 14:07:46.000000000 +0100
|
||||
@@ -70,7 +70,7 @@
|
||||
assert.equal(er.domainThrown, true);
|
||||
break;
|
||||
|
||||
- case "ENOENT, open 'this file does not exist'":
|
||||
+ case "ENOENT, no such file or directory 'this file does not exist'":
|
||||
assert.equal(er.domain, d);
|
||||
assert.equal(er.domainThrown, false);
|
||||
assert.equal(typeof er.domainBound, 'function');
|
||||
@@ -80,7 +80,7 @@
|
||||
assert.equal(typeof er.errno, 'number');
|
||||
break;
|
||||
|
||||
- case "ENOENT, open 'stream for nonexistent file'":
|
||||
+ case "ENOENT, no such file or directory 'stream for nonexistent file'":
|
||||
assert.equal(typeof er.errno, 'number');
|
||||
assert.equal(er.code, 'ENOENT');
|
||||
assert.equal(er_path, 'stream for nonexistent file');
|
||||
@@ -104,7 +104,7 @@
|
||||
assert.ok(!er.domainBound);
|
||||
break;
|
||||
|
||||
- case 'Cannot call method \'isDirectory\' of undefined':
|
||||
+ case 'Cannot read property "isDirectory" from undefined':
|
||||
assert.equal(er.domain, d);
|
||||
assert.ok(!er.domainEmitter);
|
||||
assert.ok(!er.domainBound);
|
@ -142,6 +142,17 @@ source.test.simple.list = \
|
||||
test-dgram-send-bad-arguments.js \
|
||||
test-dgram-udp4.js \
|
||||
test-dgram-unref.js \
|
||||
test-domain-crypto.js \
|
||||
test-domain-exit-dispose.js \
|
||||
test-domain-from-timer.js \
|
||||
test-domain-http-server.js \
|
||||
test-domain-implicit-fs.js \
|
||||
test-domain-multi.js \
|
||||
test-domain-nested-throw.js \
|
||||
test-domain-nested.js \
|
||||
test-domain-stack.js \
|
||||
test-domain-timers.js \
|
||||
test-domain.js \
|
||||
test-error-reporting.js \
|
||||
test-event-emitter-add-listeners.js \
|
||||
test-event-emitter-check-listener-leaks.js \
|
||||
|
@ -27,8 +27,8 @@ package net.java.avatar.js.eventloop;
|
||||
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
|
||||
import net.java.avatar.js.eventloop.Callback;
|
||||
import net.java.avatar.js.Server;
|
||||
|
||||
public final class Event {
|
||||
@ -37,12 +37,15 @@ public final class Event {
|
||||
private final Callback callback;
|
||||
private final Object[] args;
|
||||
private final AccessControlContext ctx;
|
||||
public Event(final String name, final Callback callback) {
|
||||
this(name, callback, (Object[]) null);
|
||||
private final ScriptObjectMirror domain;
|
||||
|
||||
public Event(final String name, final ScriptObjectMirror domain, final Callback callback) {
|
||||
this(name, domain, callback, (Object[]) null);
|
||||
}
|
||||
|
||||
public Event(final String name, final Callback callback, final Object arg) {
|
||||
public Event(final String name, final ScriptObjectMirror domain, final Callback callback, final Object arg) {
|
||||
this.name = name;
|
||||
this.domain = domain;
|
||||
this.callback = callback;
|
||||
this.args = new Object[1];
|
||||
this.args[0] = arg;
|
||||
@ -55,6 +58,7 @@ public final class Event {
|
||||
|
||||
public Event(final String name, final Callback callback, final Object... args) {
|
||||
this.name = name;
|
||||
this.domain = null;
|
||||
this.callback = callback;
|
||||
this.args = args == null ? null : args.clone();
|
||||
if(System.getSecurityManager() != null) {
|
||||
@ -107,4 +111,7 @@ public final class Event {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public ScriptObjectMirror getDomain() {
|
||||
return domain;
|
||||
}
|
||||
}
|
||||
|
@ -41,12 +41,16 @@ import javax.script.ScriptException;
|
||||
import jdk.nashorn.api.scripting.NashornException;
|
||||
import jdk.nashorn.internal.runtime.ECMAException;
|
||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import net.java.avatar.js.dns.DNS;
|
||||
import net.java.avatar.js.log.Logger;
|
||||
import net.java.avatar.js.log.Logging;
|
||||
import net.java.libuv.LibUV;
|
||||
import net.java.libuv.cb.AsyncCallback;
|
||||
import net.java.libuv.cb.CallbackExceptionHandler;
|
||||
import net.java.libuv.cb.CallbackDomainProvider;
|
||||
import net.java.libuv.cb.CallbackHandler;
|
||||
import net.java.libuv.cb.CallbackHandlerFactory;
|
||||
import net.java.libuv.handles.AsyncHandle;
|
||||
import net.java.libuv.handles.LoopHandle;
|
||||
|
||||
@ -69,6 +73,8 @@ public final class EventLoop {
|
||||
private Callback uncaughtExceptionHandler = null;
|
||||
private Exception pendingException = null;
|
||||
|
||||
private ScriptObjectMirror domain;
|
||||
|
||||
public static final class Handle implements AutoCloseable {
|
||||
|
||||
private final AtomicInteger hooks;
|
||||
@ -106,9 +112,14 @@ public final class EventLoop {
|
||||
uncaughtExceptionHandler = handler;
|
||||
}
|
||||
|
||||
public void nextTick(final Event event) {
|
||||
public void nextTick(final Callback cb) {
|
||||
assert Thread.currentThread() == mainThread : "called from non-event thread " + Thread.currentThread().getName();
|
||||
eventQueue.add(event);
|
||||
eventQueue.add(new Event("nextTick", cb));
|
||||
}
|
||||
|
||||
public void nextTickWithDomain(final Callback cb, ScriptObjectMirror evtDomain) {
|
||||
assert Thread.currentThread() == mainThread : "called from non-event thread " + Thread.currentThread().getName();
|
||||
eventQueue.add(new Event("nextTickWithDomain", evtDomain, cb));
|
||||
}
|
||||
|
||||
public void post(final Callback cb, Object... args) {
|
||||
@ -141,7 +152,17 @@ public final class EventLoop {
|
||||
for (Event event = eventQueue.poll();
|
||||
event != null;
|
||||
event = eventQueue.poll()) {
|
||||
processEvent(event);
|
||||
ScriptObjectMirror evtDomain = event.getDomain();
|
||||
if (evtDomain != null) {
|
||||
if (isDisposed(evtDomain)) {
|
||||
continue;
|
||||
}
|
||||
enterDomain(evtDomain);
|
||||
processEvent(event);
|
||||
exitDomain(evtDomain);
|
||||
} else {
|
||||
processEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -198,19 +219,25 @@ public final class EventLoop {
|
||||
private static final String UNCAUGHT_EXCEPTION_NAME = "uncaughtException";
|
||||
|
||||
public boolean handleCallbackException(final Exception ex) {
|
||||
|
||||
boolean handled = true;
|
||||
// callback to check if an uncaught exception handler has been registered by the user
|
||||
final Object[] registeredArgs = {null};
|
||||
if (isHandlerRegistered != null) {
|
||||
try {
|
||||
isHandlerRegistered.call(UNCAUGHT_EXCEPTION_NAME, registeredArgs);
|
||||
} catch (final Exception e) {
|
||||
return false;
|
||||
handled = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (registeredArgs[0] == null || uncaughtExceptionHandler == null) {
|
||||
// no handler registered - rethrow uncaught exceptions
|
||||
handled = false;
|
||||
}
|
||||
|
||||
if (!handled && domain == null) {
|
||||
// No domain and no uncaughtException Handler registered
|
||||
// rethrowing
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -333,6 +360,8 @@ public final class EventLoop {
|
||||
this.uvVersion = uvVersion;
|
||||
this.logging = logging;
|
||||
this.dns = new DNS(this);
|
||||
|
||||
final LoopCallbackHandler defaultHandler = new LoopCallbackHandler(this);
|
||||
this.uvLoop = new LoopHandle(new CallbackExceptionHandler() {
|
||||
@Override
|
||||
public void handle(final Exception ex) {
|
||||
@ -345,8 +374,23 @@ public final class EventLoop {
|
||||
stop();
|
||||
}
|
||||
}
|
||||
}, new LoopCallbackHandler(this));
|
||||
|
||||
},
|
||||
new CallbackHandlerFactory() {
|
||||
@Override
|
||||
public CallbackHandler newCallbackHandlerWithDomain(Object domain) {
|
||||
return new LoopCallbackHandler(EventLoop.this, domain);
|
||||
}
|
||||
@Override
|
||||
public CallbackHandler newCallbackHandler() {
|
||||
return defaultHandler;
|
||||
}
|
||||
},
|
||||
new CallbackDomainProvider() {
|
||||
@Override
|
||||
public Object getDomain() {
|
||||
return EventLoop.this.getDomain();
|
||||
}
|
||||
});
|
||||
this.instanceNumber = instanceNumber;
|
||||
this.executor = executor;
|
||||
|
||||
@ -399,4 +443,47 @@ public final class EventLoop {
|
||||
return uvLoop;
|
||||
}
|
||||
|
||||
public void setDomain(ScriptObjectMirror obj) {
|
||||
assert Thread.currentThread() == mainThread : "called from non-event thread " + Thread.currentThread().getName();
|
||||
domain = obj;
|
||||
}
|
||||
|
||||
public ScriptObjectMirror getDomain() {
|
||||
assert Thread.currentThread() == mainThread : "called from non-event thread " + Thread.currentThread().getName();
|
||||
return domain;
|
||||
}
|
||||
|
||||
public boolean isDisposed(ScriptObjectMirror domain) {
|
||||
assert Thread.currentThread() == mainThread : "called from non-event thread " + Thread.currentThread().getName();
|
||||
return Boolean.TRUE.equals(domain.getMember("_disposed"));
|
||||
}
|
||||
|
||||
public void enterDomain(ScriptObjectMirror domain) {
|
||||
assert Thread.currentThread() == mainThread : "called from non-event thread " + Thread.currentThread().getName();
|
||||
domain.callMember("enter");
|
||||
}
|
||||
|
||||
public void exitDomain(ScriptObjectMirror domain) {
|
||||
assert Thread.currentThread() == mainThread : "called from non-event thread " + Thread.currentThread().getName();
|
||||
domain.callMember("exit");
|
||||
}
|
||||
|
||||
public boolean isDisposed(Object domain) {
|
||||
if (domain instanceof ScriptObjectMirror) {
|
||||
isDisposed((ScriptObjectMirror) domain);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void enterDomain(Object domain) {
|
||||
if (domain instanceof ScriptObjectMirror) {
|
||||
enterDomain((ScriptObjectMirror) domain);
|
||||
}
|
||||
}
|
||||
|
||||
public void exitDomain(Object domain) {
|
||||
if (domain instanceof ScriptObjectMirror) {
|
||||
exitDomain((ScriptObjectMirror) domain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,16 +63,42 @@ import net.java.libuv.cb.UDPSendCallback;
|
||||
final class LoopCallbackHandler implements CallbackHandler {
|
||||
|
||||
private final EventLoop eventLoop;
|
||||
|
||||
private final Object domain;
|
||||
public LoopCallbackHandler(EventLoop eventLoop) {
|
||||
this(eventLoop, null);
|
||||
}
|
||||
|
||||
public LoopCallbackHandler(EventLoop eventLoop, Object domain) {
|
||||
this.eventLoop = eventLoop;
|
||||
this.domain = domain;
|
||||
}
|
||||
|
||||
private boolean shouldCall() {
|
||||
if (domain != null) {
|
||||
if (eventLoop.isDisposed(domain)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
eventLoop.enterDomain(domain);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void post() throws Exception {
|
||||
if (domain != null) {
|
||||
eventLoop.exitDomain(domain);
|
||||
}
|
||||
eventLoop.processQueuedEvents();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleAsyncCallback(final AsyncCallback cb, final int status) {
|
||||
try {
|
||||
cb.onSend(status);
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onSend(status);
|
||||
post();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -81,8 +107,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleCheckCallback(final CheckCallback cb, final int status) {
|
||||
try {
|
||||
cb.onCheck(status);
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onCheck(status);
|
||||
post();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -91,8 +119,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleSignalCallback(final SignalCallback cb, final int signum) {
|
||||
try {
|
||||
cb.onSignal(signum);
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onSignal(signum);
|
||||
post();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -101,8 +131,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleStreamReadCallback(final StreamReadCallback cb, final ByteBuffer data) {
|
||||
try {
|
||||
cb.onRead(data);
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onRead(data);
|
||||
post();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -111,8 +143,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleStreamRead2Callback(final StreamRead2Callback cb, final ByteBuffer data, final long handle, final int type) {
|
||||
try {
|
||||
cb.onRead2(data, handle, type);
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onRead2(data, handle, type);
|
||||
post();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -121,8 +155,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleStreamWriteCallback(final StreamWriteCallback cb, final int status, final Exception error) {
|
||||
try {
|
||||
cb.onWrite(status, error);
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onWrite(status, error);
|
||||
post();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -131,8 +167,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleStreamConnectCallback(final StreamConnectCallback cb, final int status, final Exception error) {
|
||||
try {
|
||||
cb.onConnect(status, error);
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onConnect(status, error);
|
||||
post();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -141,8 +179,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleStreamConnectionCallback(final StreamConnectionCallback cb, final int status, final Exception error) {
|
||||
try {
|
||||
cb.onConnection(status, error);
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onConnection(status, error);
|
||||
post();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -151,8 +191,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleStreamCloseCallback(final StreamCloseCallback cb) {
|
||||
try {
|
||||
cb.onClose();
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onClose();
|
||||
post();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -161,8 +203,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleStreamShutdownCallback(final StreamShutdownCallback cb, final int status, final Exception error) {
|
||||
try {
|
||||
cb.onShutdown(status, error);
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onShutdown(status, error);
|
||||
post();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -171,8 +215,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleFileCallback(final FileCallback cb, final Object context, final Exception error) {
|
||||
try {
|
||||
cb.onDone(context, error);
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onDone(context, error);
|
||||
post();
|
||||
}
|
||||
} catch (final Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -182,8 +228,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleFileCloseCallback(final FileCloseCallback cb, final Object context, final int fd, final Exception error) {
|
||||
try {
|
||||
cb.onClose(context, fd, error);
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onClose(context, fd, error);
|
||||
post();
|
||||
}
|
||||
} catch (final Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -192,8 +240,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleFileOpenCallback(final FileOpenCallback cb, final Object context, final int fd, final Exception error) {
|
||||
try {
|
||||
cb.onOpen(context, fd, error);
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onOpen(context, fd, error);
|
||||
post();
|
||||
}
|
||||
} catch (final Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -202,8 +252,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleFileReadCallback(final FileReadCallback cb, final Object context, final int bytesRead, final ByteBuffer data, final Exception error) {
|
||||
try {
|
||||
cb.onRead(context, bytesRead, data, error);
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onRead(context, bytesRead, data, error);
|
||||
post();
|
||||
}
|
||||
} catch (final Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -212,8 +264,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleFileReadDirCallback(final FileReadDirCallback cb, final Object context, final String[] names, final Exception error) {
|
||||
try {
|
||||
cb.onReadDir(context, names, error);
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onReadDir(context, names, error);
|
||||
post();
|
||||
}
|
||||
} catch (final Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -222,8 +276,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleFileReadLinkCallback(final FileReadLinkCallback cb, final Object context, final String name, final Exception error) {
|
||||
try {
|
||||
cb.onReadLink(context, name, error);
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onReadLink(context, name, error);
|
||||
post();
|
||||
}
|
||||
} catch (final Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -232,8 +288,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleFileStatsCallback(final FileStatsCallback cb, final Object context, final Stats stats, final Exception error) {
|
||||
try {
|
||||
cb.onStats(context, stats, error);
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onStats(context, stats, error);
|
||||
post();
|
||||
}
|
||||
} catch (final Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -242,8 +300,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleFileUTimeCallback(final FileUTimeCallback cb, final Object context, final long time, final Exception error) {
|
||||
try {
|
||||
cb.onUTime(context, time, error);
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onUTime(context, time, error);
|
||||
post();
|
||||
}
|
||||
} catch (final Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -252,8 +312,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleFileWriteCallback(final FileWriteCallback cb, final Object context, final int bytesWritten, final Exception error) {
|
||||
try {
|
||||
cb.onWrite(context, bytesWritten, error);
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onWrite(context, bytesWritten, error);
|
||||
post();
|
||||
}
|
||||
} catch (final Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -262,8 +324,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleFileEventCallback(FileEventCallback cb, int status, String event, String filename) {
|
||||
try {
|
||||
cb.onEvent(status, event, filename);
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onEvent(status, event, filename);
|
||||
post();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -273,7 +337,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleFilePollCallback(FilePollCallback cb, int status, Stats previous, Stats current) {
|
||||
try {
|
||||
cb.onPoll(status, previous, current);
|
||||
if (shouldCall()) {
|
||||
cb.onPoll(status, previous, current);
|
||||
post();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -282,7 +349,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleFilePollStopCallback(FilePollStopCallback cb) {
|
||||
try {
|
||||
cb.onStop();
|
||||
if (shouldCall()) {
|
||||
cb.onStop();
|
||||
post();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -291,7 +361,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleProcessCloseCallback(ProcessCloseCallback cb) {
|
||||
try {
|
||||
cb.onClose();
|
||||
if (shouldCall()) {
|
||||
cb.onClose();
|
||||
post();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -300,7 +373,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleProcessExitCallback(ProcessExitCallback cb, int status, int signal, Exception error) {
|
||||
try {
|
||||
cb.onExit(status, signal, error);
|
||||
if (shouldCall()) {
|
||||
cb.onExit(status, signal, error);
|
||||
post();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -309,8 +385,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleTimerCallback(final TimerCallback cb, final int status) {
|
||||
try {
|
||||
cb.onTimer(status);
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onTimer(status);
|
||||
post();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -319,8 +397,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleUDPRecvCallback(final UDPRecvCallback cb, final int nread, final ByteBuffer data, final Address address) {
|
||||
try {
|
||||
cb.onRecv(nread, data, address);
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onRecv(nread, data, address);
|
||||
post();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -329,8 +409,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleUDPSendCallback(final UDPSendCallback cb, final int status, final Exception error) {
|
||||
try {
|
||||
cb.onSend(status, error);
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onSend(status, error);
|
||||
post();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -339,8 +421,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleUDPCloseCallback(final UDPCloseCallback cb) {
|
||||
try {
|
||||
cb.onClose();
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onClose();
|
||||
post();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
@ -349,8 +433,10 @@ final class LoopCallbackHandler implements CallbackHandler {
|
||||
@Override
|
||||
public void handleIdleCallback(IdleCallback cb, int status) {
|
||||
try {
|
||||
cb.onIdle(status);
|
||||
eventLoop.processQueuedEvents();
|
||||
if (shouldCall()) {
|
||||
cb.onIdle(status);
|
||||
post();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
eventLoop.loop().getExceptionHandler().handle(ex);
|
||||
}
|
||||
|
@ -61,7 +61,6 @@ var eventloop = __avatar.eventloop;
|
||||
var LibUV = Packages.net.java.libuv.LibUV;
|
||||
var Process = Packages.net.java.avatar.js.os.Process;
|
||||
var Server = Packages.net.java.avatar.js.Server;
|
||||
var Event = Packages.net.java.avatar.js.eventloop.Event
|
||||
var Constants = Packages.net.java.avatar.js.constants.Constants;
|
||||
var Signals = Packages.net.java.libuv.handles.SignalHandle;
|
||||
|
||||
@ -430,16 +429,14 @@ Object.defineProperty(exports, 'hrtime', {
|
||||
|
||||
Object.defineProperty(exports, 'nextTick', {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
value: function(callback) {
|
||||
if (this._exiting) {
|
||||
return;
|
||||
}
|
||||
eventloop.nextTick(
|
||||
new Event('nextTick', function(name, args) {
|
||||
callback();
|
||||
}
|
||||
)
|
||||
);
|
||||
eventloop.nextTick(function(name, args) {
|
||||
callback();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -588,8 +585,36 @@ exports.openStdin = function() {
|
||||
}
|
||||
|
||||
exports._usingDomains = function() {
|
||||
// redefine nextTick at this time to speedup
|
||||
// domain event posting
|
||||
Object.defineProperty(exports, 'nextTick', {
|
||||
enumerable: true,
|
||||
value: function(callback) {
|
||||
if (this._exiting) {
|
||||
return;
|
||||
}
|
||||
eventloop.nextTickWithDomain(function(name, args) {
|
||||
callback();
|
||||
}, process.domain)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var ScriptUtils = Packages.jdk.nashorn.api.scripting.ScriptUtils
|
||||
Object.defineProperty(exports, 'domain', {
|
||||
enumerable : true,
|
||||
set : function(domain) {
|
||||
if (domain) {
|
||||
eventloop.domain = domain;
|
||||
} else {
|
||||
eventloop.domain = null;
|
||||
}
|
||||
},
|
||||
get : function() {
|
||||
return ScriptUtils.unwrap(eventloop.domain);
|
||||
}
|
||||
});
|
||||
|
||||
var Check = Packages.net.java.libuv.handles.CheckHandle;
|
||||
var Idle = Packages.net.java.libuv.handles.IdleHandle;
|
||||
var checkHandle = new Check(eventloop.loop());
|
||||
|
@ -200,6 +200,67 @@ var gc = global.gc;
|
||||
console.log(this.stack);
|
||||
};
|
||||
|
||||
var fatalProcessing = function(er) {
|
||||
var caught = false;
|
||||
if (process.domain) { // From nodejs
|
||||
var domain = process.domain;
|
||||
var domainModule = NativeModule.require('domain');
|
||||
var domainStack = domainModule._stack;
|
||||
|
||||
// ignore errors on disposed domains.
|
||||
//
|
||||
// XXX This is a bit stupid. We should probably get rid of
|
||||
// domain.dispose() altogether. It's almost always a terrible
|
||||
// idea. --isaacs
|
||||
if (domain._disposed)
|
||||
return true;
|
||||
|
||||
er.domain = domain;
|
||||
er.domainThrown = true;
|
||||
// wrap this in a try/catch so we don't get infinite throwing
|
||||
try {
|
||||
// One of three things will happen here.
|
||||
//
|
||||
// 1. There is a handler, caught = true
|
||||
// 2. There is no handler, caught = false
|
||||
// 3. It throws, caught = false
|
||||
//
|
||||
// If caught is false after this, then there's no need to exit()
|
||||
// the domain, because we're going to crash the process anyway.
|
||||
caught = domain.emit('error', er);
|
||||
// Exit all domains on the stack. Uncaught exceptions end the
|
||||
// current tick and no domains should be left on the stack
|
||||
// between ticks.
|
||||
var domainModule = NativeModule.require('domain');
|
||||
domainStack.length = 0;
|
||||
domainModule.active = process.domain = null;
|
||||
} catch (er2) {
|
||||
// The domain error handler threw! oh no!
|
||||
// See if another domain can catch THIS error,
|
||||
// or else crash on the original one.
|
||||
// If the user already exited it, then don't double-exit.
|
||||
if (domain === domainModule.active)
|
||||
domainStack.pop();
|
||||
if (domainStack.length) {
|
||||
var parentDomain = domainStack[domainStack.length - 1];
|
||||
process.domain = domainModule.active = parentDomain;
|
||||
caught = fatalProcessing(er2);
|
||||
} else
|
||||
caught = false;
|
||||
}
|
||||
} else {
|
||||
caught = process.emit('uncaughtException', er);
|
||||
}
|
||||
|
||||
// Avatar-js specific handling,
|
||||
// exit is handled in the class that is catching the rethrown er
|
||||
if (!caught) {
|
||||
throw er;
|
||||
}
|
||||
|
||||
return caught;
|
||||
};
|
||||
|
||||
__avatar.eventloop.setUncaughtExceptionHandler(
|
||||
function(name, args) {
|
||||
var listeners = process.listeners('uncaughtException');
|
||||
@ -208,13 +269,12 @@ var gc = global.gc;
|
||||
}
|
||||
},
|
||||
function(name, args) {
|
||||
var ctx = Packages.net.java.avatar.js.eventloop.EventLoop;
|
||||
var e = new Error();
|
||||
var ex = args[0];
|
||||
for (var k in ex) {
|
||||
e[k] = ex[k];
|
||||
}
|
||||
process.emit(name, e);
|
||||
fatalProcessing(e);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -32,7 +32,14 @@
|
||||
var that = this;
|
||||
this._timer.setTimerFiredCallback(function(status) {
|
||||
if (that.ontimeout) {
|
||||
// When a timer is unref, the domain is set on the wrap.
|
||||
if (that.domain) {
|
||||
that.domain.enter();
|
||||
}
|
||||
that.ontimeout();
|
||||
if (that.domain) {
|
||||
that.domain.exit();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user