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

stream: don't deadlock duplexpair #29836

Closed
wants to merge 4 commits into from
Closed

Conversation

ronag
Copy link
Member

@ronag ronag commented Oct 3, 2019

If nothing is buffered then _read will not be called and the callback will not invoked, effectivly deadlocking.

Fixes: #29758
Refs: #29649

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines

awwright and others added 2 commits September 24, 2019 13:47
If nothing is buffered then _read will not be called and the
callback will not invoked, effectivly deadlocking.

Fixes: nodejs#29758
this[kOtherSide].push(chunk);
if (!this[kOtherSide].readableLength) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we have no readableLength _read will never be called.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be clear that I’m not misunderstanding – this is because _read() was already called?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But wouldn’t .push() schedule another ._read() call, because the readable side’s buffer is empty once the data from .push() is used?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@addaleax push(chunk) should not schedule another read if push(null) is called in the same tick.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current implementation disregards this invariant of Readable.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This made me consider why push(null) is called before _read. Could be that _final is called before all writes having finished. Let me check.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, it simply that an empty push will not trigger another read, as it is sensible to assume that if we couldn't push data then there is no data

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, that kind of makes sense, but it’s also weird that .push() with an empty chunk leads to different behaviour than .push() with a non-empty chunk…

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, I've been trying to get my head around it for a few days. But as you write, it's weird but makes sense. The alternative is more confusing and leads to other problems such as livelocks.

Copy link
Member

@addaleax addaleax left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this variant seems a bit more intuitive to me 👍

@lpinca
Copy link
Member

lpinca commented Oct 3, 2019

This is basically the workaround I suggested in #29758 (comment).

@ronag
Copy link
Member Author

ronag commented Oct 3, 2019

This is basically the workaround I suggested in #29758 (comment).

Yep, it took me a bit longer to come to the same conclusion.

@awwright
Copy link
Contributor

awwright commented Oct 4, 2019

To rephrase #29649 (comment): this looks good, I'm just surprised it requires a fix to the DuplexPair implementation (the part I was hoping to not change, since that code is copied in so many places)—but I guess that makes sense.

@Trott Trott added author ready PRs that have at least one approval, no pending requests for changes, and a CI started. stream Issues and PRs related to the stream subsystem. labels Oct 5, 2019
@nodejs-github-bot
Copy link
Collaborator

@Trott Trott added the http Issues or PRs related to the http subsystem. label Oct 5, 2019
@nodejs-github-bot
Copy link
Collaborator

Trott pushed a commit that referenced this pull request Oct 6, 2019
If nothing is buffered then _read will not be called and the
callback will not be invoked, effectivly deadlocking.

Fixes: #29758

PR-URL: #29836
Refs: #29649
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Minwoo Jung <[email protected]>
Trott pushed a commit that referenced this pull request Oct 6, 2019
PR-URL: #29836
Refs: #29758
Refs: #29649
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Minwoo Jung <[email protected]>
@Trott
Copy link
Member

Trott commented Oct 6, 2019

Landed in 0b495a8...28c3a9d

@Trott Trott closed this Oct 6, 2019
BridgeAR pushed a commit that referenced this pull request Oct 9, 2019
If nothing is buffered then _read will not be called and the
callback will not be invoked, effectivly deadlocking.

Fixes: #29758

PR-URL: #29836
Refs: #29649
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Minwoo Jung <[email protected]>
BridgeAR pushed a commit that referenced this pull request Oct 9, 2019
PR-URL: #29836
Refs: #29758
Refs: #29649
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: Luigi Pinca <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Minwoo Jung <[email protected]>
@BridgeAR BridgeAR mentioned this pull request Oct 10, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
author ready PRs that have at least one approval, no pending requests for changes, and a CI started. http Issues or PRs related to the http subsystem. stream Issues and PRs related to the stream subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

stream: certain sequence of Writable#write and Writable#end will not end stream
8 participants