-
Notifications
You must be signed in to change notification settings - Fork 570
syscall: fallback to process.exit when available #710
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Do we care about the issue mentioned here, which concludes
|
Can you elaborate? Why do we not care? This seems to have the potential to break expected behavior, if stdout isn't flushed before exit. |
@flimzy, |
Thanks for this @Lekensteyn. At a high level, this makes sense. |
@@ -67,6 +67,10 @@ func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) { | |||
return uintptr(array.Length()), 0, 0 | |||
} | |||
if trap == SYS_EXIT { | |||
process := js.Global.Get("process") | |||
if process != js.Undefined { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style-wise, this is a good time to inline process := js.Global.Get("process")
into the if statement:
if process := js.Global.Get("process"); process != js.Undefined {
process.Call("exit", a1)
}
process
is only needed inside the if statement, so it's good to give it a smaller scope.
(/cc @gmlewis FYI.)
Does output to stdout not normally block in Go? |
I think it does. Are you referring to how writing to |
My concern, without any attempt to test this, is that something like this might lead to lost output, particularly in tests running in Node.js (which I think is only place this patch matters, right?
If my understanding of the SO link above, plus Go/GopherJS is correct, the Println would be translated to an async nidejs syscall, but GopherJS would treat it as if it were a completed blocking operation. So it the Node.js call may not actually complete before the program exists. It's certainly quite possible that I'm wrong about one or more of the pieces to this puzzle, though. In that case, please accept my apologies for wasting time. :) |
"go test" currently always fails with "fatal error: all goroutines are asleep - deadlock!". In fact, all programs that use "os.Exit" will fail with this. It turns out that the current "runtime.Goexit" function throws an exception which propagates up which violates the expected behavior of the exit syscall (which should not return). Therefore call "process.exit" when available. Fixes gopherjs#626
printToConsole does some internal line buffering (not even involving the stdio layer) which is only flushed on normal exit via $flushConsole. When using process.exit, this is not called though. Therefore avoid the internal buffering, and use Node's stdio directly.
b91438e
to
3416b8f
Compare
@flimzy Your test (or a main function which calls
I have just pushed one that implements the former, WDYT? The generated code is a bit ugly though, buffer = $ifaceNil;
bufferFrom = $global.Buffer.from;
if (!(bufferFrom === undefined)) {
buffer = new $jsObjectPtr(bufferFrom(array));
} else {
buffer = new $jsObjectPtr(new ($global.Buffer)(array));
}
if (a1 === 1) {
process.stdout.write($externalize(buffer, $emptyInterface));
} else {
process.stderr.write($externalize(buffer, $emptyInterface));
} it could also have been written as: if (Buffer.from) {
buffer = Buffer.from(array);
} else {
buffer = new Buffer(array);
}
if (a1 === 1) {
process.stdout.write(buffer);
} else {
process.stderr.write(buffer);
} Relevant other resources: |
@Lekensteyn Thanks for testing that. Your approach of using |
We should take this documented behavior into account:
(Source: https://github.com/gopherjs/gopherjs#application-lifecycle.) Do we want to change that? It might break existing programs. There might've been a good reason for making that design decision, we should remember what it was. (Or does it not apply because this change is affects |
The rationale for the documented behavior for browsers is noted in #229 (comment). It does not apply to node. At least, not when you run the script directly, I don't think that importing a gopherjs program as package is supported, is it? Also note that with the syscalls package installed, |
Ping |
Thanks for the ping, and sorry about the delay. I will try to find some time to work on this. I still need to get a better understanding of the change and gain confidence that it doesn't have any unexpected unintended side-effects. |
Poke :-) |
Any updates on this one? |
Is any of this still relevant after the syscall rewwork cc/ @nevkontakte |
I think this is obsolete as of #1111. |
"go test" currently always fails with "fatal error: all goroutines are
asleep - deadlock!". In fact, all programs that use "os.Exit" will fail
with this.
It turns out that the current "runtime.Goexit" function throws an
exception which propagates up which violates the expected behavior of
the exit syscall (which should not return). Therefore call
"process.exit" when available.
Fixes #626
Test with
go test
on any package or just:Also note that any functions registered with
process.on("exit", ...)
will still be executed. Not ideal, but this is better than nothing when syscalls are not available.