Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

uv_pipe_getsockname blocks on widows for non-overlapped file #1313

Closed
Keno opened this issue Jun 11, 2014 · 8 comments
Closed

uv_pipe_getsockname blocks on widows for non-overlapped file #1313

Keno opened this issue Jun 11, 2014 · 8 comments

Comments

@Keno
Copy link
Contributor

Keno commented Jun 11, 2014

The problem is that the zero-read ReadFile on the thread pool holds a kernel lock, hence NtQueryInformationFile is stuck until the next I/O event.

@saghul
Copy link
Contributor

saghul commented Jun 11, 2014

Hey @Keno! Can you pleas describe when this could happen? I added uv_pipe_getsockname, but I wasn't aware of this :-S Also, any pointers to a possible solution would be appreciated.

@Keno
Copy link
Contributor Author

Keno commented Jun 11, 2014

Yeah, this happens for any pipe that has UV_HANDLE_NON_OVERLAPPED_PIPE and from which you are currently reading. This came up in JuliaLang/julia#7174 where I proposed cancelling the I/O, but it turns out that doesn't really work (segfaults on occaison).

@vtjnash
Copy link
Contributor

vtjnash commented Jun 11, 2014

the occasional segfault came because we closed the pipe when we saw the UV_ECANCELED error that is returned. As Keno mentioned, ReadFile grabs a lock on the file object, and prevents any other interaction with it (such as NtQueryInformationFile) until the read returns.

I think the necessary solution would be to implement a lock around the ReadFile, so that uv_pipe_getsockname can detect that we are blocked, abort the Read while notifying ReadFile to wait, do the getsockname call, then notify the ReadFile call to restart.

@vtjnash
Copy link
Contributor

vtjnash commented Jun 15, 2014

Would it be acceptable to just call uv_pipe_getsockname when initializing the pipe, and cache the result? Making this work,without accidentally discarding a write, seems rather challenging.

@Keno
Copy link
Contributor Author

Keno commented Jun 19, 2014

bump.

@saghul
Copy link
Contributor

saghul commented Jun 20, 2014

I'm uncertain about how to go on this one. We could indeed cache the result, but then so could the application (Julia in this case), right? Another posibility would be to check if the the user called uv_read_start and stop it, get the sockname and call start again internally, but I'm not sure the stopping happens synchronously...

@vtjnash
Copy link
Contributor

vtjnash commented Jun 20, 2014

uv_read_stop does not cancel the read call. If the device supports it, CancelSynchronousIo could be issued to accomplish this. However, ReadFile and all synchronous WriteFile calls would need to know how to handle this result. (Also, that API was introduced in Vista -- XP only has CancelIo)

@vtjnash
Copy link
Contributor

vtjnash commented Jul 12, 2014

Some more trivia:

Microsoft reports that this "feature" was by design: https://connect.microsoft.com/VisualStudio/feedback/details/362169/getfinalpathnamebyhandle-api-hungs

Microsoft apparently gets around this bug by loading a kernel extension from their process memory, which can copy the filename memory buffer from kernel space to user space: http://www.codeproject.com/Articles/18975/Listing-Used-Files

(A GPL3 version which incorporates a similar workaround: http://sourceforge.net/projects/processhacker/ via the KProcessHacker kernel module and kph.c for live-loading of the kernel module)

@saghul saghul closed this as completed in 837c62c Aug 9, 2014
bzoz added a commit to JaneaSystems/libuv that referenced this issue Mar 23, 2017
Add a thread that will interrupt uv_pipe_zero_readdile_thread_proc
every half second. This allows other processes to access the pipe
without deadlocking

Ref: joyent/libuv#1313
Ref: nodejs/node#10836
cjihrig pushed a commit to libuv/libuv that referenced this issue May 1, 2017
Refs: joyent/libuv#1313
PR-URL: #1321
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants