Skip to content
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

hang on exit after listen() #2331

Closed
JeffBezanson opened this issue Feb 16, 2013 · 7 comments
Closed

hang on exit after listen() #2331

JeffBezanson opened this issue Feb 16, 2013 · 7 comments
Assignees
Labels
bug Indicates an unexpected problem or unintended behavior

Comments

@JeffBezanson
Copy link
Member

If I type this:

julia> listen(9008) do sock,s
        s = accept(sock)
       s.readcb = (args...)->(l=readline(s);write(s,l);true)
       start_reading(s)
       end
TcpSocket(connected,0 bytes waiting)

and then quit the repl, julia hangs. Here is a stacktrace during the hang:

^C
Program received signal SIGINT, Interrupt.
0x00007ffff5b36df9 in syscall () from /lib/libc.so.6
(gdb) bt
#0  0x00007ffff5b36df9 in syscall () from /lib/libc.so.6
#1  0x00007ffff675bf26 in uv__epoll_wait (epfd=9, events=0x7fffffffb030, 
    nevents=1024, timeout=-1) at src/unix/linux/syscalls.c:282
#2  0x00007ffff6758c8c in uv__io_poll (loop=0x7ffff7756420, timeout=-1)
    at src/unix/linux/linux-core.c:184
#3  0x00007ffff6743b72 in uv__run (loop=0x7ffff7756420) at src/unix/core.c:271
#4  0x00007ffff6743bd1 in uv_run (loop=0x7ffff7756420) at src/unix/core.c:279
#5  0x00007ffff67164f6 in uv_atexit_hook () at init.c:289
@pao
Copy link
Member

pao commented Feb 16, 2013

Only seems to happen at the REPL. Same thing stuffed in a script seems fine.

@vtjnash
Copy link
Member

vtjnash commented Feb 16, 2013

This is the same problem we had with pipes. libuv marks the server pipe as writable (https://github.com/joyent/libuv/blob/master/src/unix/tcp.c#L63) so we try to wait for it to drain & shutdown, except that it's not actually writable so it can't respond to the shutdown request (although it thinks that it can)

i'm guessing that it doesn't happen in your script since you don't call uv_run() prior to exiting, so the socket is never fully created and the shutdown works properly

@JeffBezanson
Copy link
Member Author

Is there an official way to call uv_run to make sure we enter the event loop? I've used wait(RemoteRef()) for this, but that's hacky.

@Keno
Copy link
Member

Keno commented Feb 16, 2013

Base.runeventloop() or whatever it is called now.

@pao
Copy link
Member

pao commented Feb 16, 2013

i'm guessing that it doesn't happen in your script since you don't call uv_run() prior to exiting, so the socket is never fully created and the shutdown works properly

The socket is definitely open, as I was able to netcat to it. I'm not sure what "fully created" means in the libuv context, though.

@vtjnash
Copy link
Member

vtjnash commented Feb 17, 2013

i guess the socket was fully created then. (some initialization may be delayed until the call to uv_run, which would be after the closing flags got set, if this occurred in uv_atexit_hook for the first time). I'm not sure what the difference would be then. maybe the REPL is doing something funny to the way exit(0) gets called?

I recommend not using Base.runeventloop(), since it may expect to be run from the scheduler. yielding to the scheduler should be sufficient. I think that it is setup such that when the main task terminates, exit(0) gets called explicitly. if you don't want that to happen, I would do current_thread().runnable = false; yield() in the main task. however, Jeff may have to double check my logic here.

@JeffBezanson
Copy link
Member Author

Fixed by 32f365d

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Indicates an unexpected problem or unintended behavior
Projects
None yet
Development

No branches or pull requests

4 participants