Sitelet https://github.com/nodejs/node/issues/30864
Skip to content

stream, net, http, http2: destroy while active race #30864

Description

@ronag

Given the context of #30837.

Where basically we have the problem of destroying a handle while it's being actively used during read/write causing "unexpected" errors.

  1. I believe we might have similar problems in net, http, http2 and also quic. Where we can destroy the handle while it's in active use. Is this something we need to address?

  2. Can we find a generic solution in streams as to avoid this "race"? e.g. in Writable we could defer calling _destroy until the active write has completed or failed. Readable would be a bit more tricky without changing or adding to the API.

I'm unsure how big of a problem this actually is.

Activity

  1. changed the title [-]stream, net, http, http2: destroy while active[/-] [+]stream, net, http, http2: destroy while active race[/+] on Dec 9, 2019
  2. ronag commented on Dec 9, 2019

    @ronag
    MemberAuthor
  3. mcollina commented on Dec 9, 2019

    @mcollina
    SponsorMember

    I would say this is expected. destroy() signifies abnormal termination, and possibly it could result in an error.

  4. ronag commented on Dec 9, 2019

    @ronag
    MemberAuthor

    @mcollina: Hm, I think that also makes sense. Given that, what is your take on #30837?

  5. ronag commented on Dec 11, 2019

    @ronag
    MemberAuthor

    Given @addaleax comment and reading a bit about fd I found the following paragraph from close

    It is probably unwise to close file descriptors while they may be in use by system calls in other threads in the same process. Since a file descriptor may be reused, there are some obscure race conditions that may cause unintended side effects.

    So basically, we should (must?) wait for any pending operations before closing (_destroy:ing) a file descriptor. The fix we applied in #30837 for fs should "probably" also apply in other places where file descriptor reuse is possible?

  6. addaleax commented on Dec 11, 2019

    @addaleax
    Member

    @ronag Yeah, I feel like it would be very tricky to get this right for anything that uses the threadpool. Network sockets luckily don’t (at least on Unix).

  7. ronag commented on Dec 11, 2019

    @ronag
    MemberAuthor

    Yeah, I feel like it would be very tricky to get this right for anything that uses the threadpool.

    Not sure I quite understand the implications here.

    Network sockets luckily don’t (at least on Unix).

    So I guess net would be a good next candidate to look into further applying your fix on?

  8. addaleax commented on Dec 11, 2019

    @addaleax
    Member

    Yeah, I feel like it would be very tricky to get this right for anything that uses the threadpool.

    Not sure I quite understand the implications here.

    Basically what the close(2) man page says – if it’s possible that the fd is being used for a syscall in one thread of the threadpool, we should not be calling close() concurrently.

    Network sockets luckily don’t (at least on Unix).

    So I guess net would be a good next candidate to look into further applying your fix on?

    I’m not sure that they need it, because they don’t use the threadpool, unlike fs operations. Everything is single-threaded here, and once the handle is closed by uv_close(), we won’t access it anymore.

  9. ronag commented on Dec 11, 2019

    @ronag
    MemberAuthor

    Basically what the close(2) man page says – if it’s possible that the fd is being used for a syscall in one thread of the threadpool, we should not be calling close() concurrently.

    Ah, thank you! That makes things much more understandable for me.

  10. ronag commented on Dec 11, 2019

    @ronag
    MemberAuthor

    @addaleax If fs is the only thing that uses the threadpool and can encounter this race I think we can close this issue?

  11. addaleax commented on Dec 11, 2019

    @addaleax
    Member

    @ronag It’s the only thing I could tell you right now that it’s affected by this issue, yes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions