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

Proc::Async.bind-stdin leaves a unix socket open #6461

Open
p6rt opened this issue Aug 21, 2017 · 3 comments
Open

Proc::Async.bind-stdin leaves a unix socket open #6461

p6rt opened this issue Aug 21, 2017 · 3 comments

Comments

@p6rt
Copy link

p6rt commented Aug 21, 2017

Migrated from rt.perl.org#131940 (status was 'open')

Searchable as RT131940$

@p6rt
Copy link
Author

p6rt commented Aug 21, 2017

From shoichikaji@gmail.com

(Please note that the following is available at gist too.
https://gist.github.com/skaji/b0b210304e932445890f2a28cf7f53b0 )

I found that Proc​::Async.bind-stdin left a unix socket open.
Should I call some methods on Proc​::Async if I use bind-stdin?

## How to reproduce this issue

The following script demonstrates this
issue.https://gist.github.com/skaji/b0b210304e932445890f2a28cf7f53b0#file-bind-stdin-test-p6


❯ perl6 bind-stdin-test.p6 20 >/dev/null
run 20 tests, leaves 152 files open
❯ perl6 bind-stdin-test.p6 21 >/dev/null
run 21 tests, leaves 153 files open
❯ perl6 bind-stdin-test.p6 22 >/dev/null
run 22 tests, leaves 154 files open
❯ perl6 bind-stdin-test.p6 23 >/dev/null
run 23 tests, leaves 155 files open


This shows everytime we call bind-stdin method, the number of open
files increases.

The output of lsof -p PID in macos is below​:


...
moar 44821 skaji 139u unix 0xf2addbda53e4c6b7 0t0 ->(none)
moar 44821 skaji 140u unix 0xf2addbda53e4c077 0t0 ->(none)
moar 44821 skaji 141u unix 0xf2addbda53e4c90f 0t0
->0xf2addbda53e4c77f


See https://gist.github.com/skaji/b0b210304e932445890f2a28cf7f53b0#file-zz-result-on-macos-txt

## My environment

* This is Rakudo version 2017.07-202-ge3e29c5 built on MoarVM version
2017.07-444-g88c6851
* Both macOS Sierra (10.12.6) and Ubuntu 16.04 64bit (linux 4.4.0)

@p6rt
Copy link
Author

p6rt commented Aug 22, 2017

From @skids

On Mon, 21 Aug 2017 04​:38​:48 -0700, shoichikaji@​gmail.com wrote​:

This shows everytime we call bind-stdin method, the number of open
files increases.

I've been able to confirm that the particular file handles being leaked
are the parent process's write uv_pipes towards the bound stdin. Obviously
the parent process does not need these filehandles anymore after building
a pipeline between children, but it ends up keeping them anyway.

I don't see anything else in the Proc​::Async API that would help to close these
descriptors. The .close-stdin method demands that the (incompatible with
.bind-stdin) :w option has been supplied.

Internally, handles are fed to a uv_process_t. This libuv object has a uv_close,
but not for particular filehandles... and I haven't used enough libuv to know
if that also kills the process. How this object actually stores these handles
is opaque, so we have no guarantee that we can reach in and grab the handles and
close them without causing re-use/async/signal issues.

Note that if we are (unlike in the example) interested in the output of the
whole pipeline, we would need to avoid also closing the stdout of the final
stage, and depending on libuv implementation this might be made tricky.

The Proc​::Async class and its associated MoarVM backend are pretty convoluted code
with lots of promises being handed about.,, as any async abstraction implementation
is want to be. Also it is not that easy to work on from outside the core tree given
highly restrictive encapsulation. So far I have not seen any indication of anything
that is intended to clean up these particular filehandles. It might be as simple as​:

- @​blockers.push($!stdin-fd.then({ $!stdin-fd := .result }));
+ @​blockers.push($!stdin-fd.then({ $!stdin-fd := .result; $!ready_promise := $!ready_promise.then({ # find and close the C filehandle and alter the libuv object so it knows it was closed
  })

...but that supposes a lot of things are safe to do which probably are not safe to do.

@p6rt
Copy link
Author

p6rt commented Aug 22, 2017

The RT System itself - Status changed from 'new' to 'open'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant