Skip to content
This repository has been archived by the owner on Aug 11, 2020. It is now read-only.

src,quic: add custom smart pointer for BaseObjects #141

Closed
wants to merge 9 commits into from

Conversation

addaleax
Copy link
Member

This is in response to conversation with @jasnell; the previous approach taken in the QUIC codebase, relying mostly on std::shared_ptr and std::unique_ptr, conflicts with BaseObject’s own lifetime management. In order to avoid these conflicts, this introduces a new type of smart pointer to Node.js specifically for managing and observing the lifetime of BaseObject subclass instances.

The first two commits are from node/master, included so that semantic conflicts with them can be avoided early. These will go away once we rebase.

What also came out of that conversation is that, whether we take this approach or not, some documentation on the BaseObject lifetime management (and the Environment cleanup functionality) is necessary. I don’t think it should hold up this PR, but it would make a good follow-up, especially given that this PR does modify the semantics there and such documentation would look different depending on whether this PR lands.


Main commit:

src: introduce custom smart pointers for BaseObjects

Referring to BaseObject instances using standard C++ smart pointers
can interfere with BaseObject’s own cleanup mechanisms
(explicit delete, delete-on-GC and delete-on-cleanup).

Introducing custom smart pointers allows referring to BaseObjects
safely while keeping those mechanisms intact.

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

This simplifies the implementation of ELDHistogram a bit,
and more generally allows us to have weak JS references
associated with `HandleWrap`s.

PR-URL: nodejs/node#29317
Reviewed-By: James M Snell <[email protected]>
In 0af62aa, this was overlooked, with it
possibly leading to hard crashes.

Refs: nodejs/node#29317

PR-URL: nodejs/node#29640
Reviewed-By: Ben Coe <[email protected]>
Reviewed-By: Rich Trott <[email protected]>
Referring to `BaseObject` instances using standard C++ smart pointers
can interfere with BaseObject’s own cleanup mechanisms
(explicit delete, delete-on-GC and delete-on-cleanup).

Introducing custom smart pointers allows referring to `BaseObject`s
safely while keeping those mechanisms intact.
Previously, the QuicSocket instance would always be destroyed first
during cleanup (because it is a `HandleWrap`), destroying the other
native objects associated with it in the process. This makes sure
that cleanup also works when the session is detached from the
“real” network socket. In particular, this is useful for the future
possibility of fully detaching sessions from sockets.
Environment* env_;
PointerData* pointer_data_ = nullptr;
Copy link
Member Author

Choose a reason for hiding this comment

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

Btw, I’ve considered merging the two members into one tagged pointer (Environment* by default, PointerData* otherwise + an Environment* member in PointerData) in order to avoid the extra memory overhead for most BaseObjects, but playing around with similar code and looking at the compiler output I got worried about the added CPU cost, and so I let that be for now.

Copy link
Member

@jasnell jasnell left a comment

Choose a reason for hiding this comment

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

Very nice

@jasnell
Copy link
Member

jasnell commented Sep 30, 2019

@addaleax ... with regards to the two upstream commits, should I go ahead and land this now or pull in the latest round of updates from nodejs/node then drop the extra commits from this PR?

@addaleax
Copy link
Member Author

addaleax commented Oct 1, 2019

@jasnell I’ve pushed another commit with the move constructors suggested in the TODO comment and more tests. (Just so you’re aware as the sole reviewer so far.)

@addaleax ... with regards to the two upstream commits, should I go ahead and land this now or pull in the latest round of updates from nodejs/node then drop the extra commits from this PR?

I don’t think it makes much of a difference – the commits should be dropped automatically once we rebase. Feel free to go with what’s easier for you :)

@jasnell
Copy link
Member

jasnell commented Oct 1, 2019

Ok, I'll land this first a bit later on today then do a rebase and force update to master by the end of the day.

@jasnell
Copy link
Member

jasnell commented Oct 1, 2019

Landed!

@jasnell jasnell closed this Oct 1, 2019
jasnell pushed a commit that referenced this pull request Oct 1, 2019
Referring to `BaseObject` instances using standard C++ smart pointers
can interfere with BaseObject’s own cleanup mechanisms
(explicit delete, delete-on-GC and delete-on-cleanup).

Introducing custom smart pointers allows referring to `BaseObject`s
safely while keeping those mechanisms intact.

PR-URL: #141
Reviewed-By: James M Snell <[email protected]>
jasnell pushed a commit that referenced this pull request Oct 1, 2019
jasnell pushed a commit that referenced this pull request Oct 1, 2019
jasnell pushed a commit that referenced this pull request Oct 1, 2019
jasnell pushed a commit that referenced this pull request Oct 1, 2019
Previously, the QuicSocket instance would always be destroyed first
during cleanup (because it is a `HandleWrap`), destroying the other
native objects associated with it in the process. This makes sure
that cleanup also works when the session is detached from the
“real” network socket. In particular, this is useful for the future
possibility of fully detaching sessions from sockets.

PR-URL: #141
Reviewed-By: James M Snell <[email protected]>
@addaleax addaleax deleted the teardown-fixes-2 branch October 1, 2019 20:23
jasnell pushed a commit that referenced this pull request Oct 2, 2019
Referring to `BaseObject` instances using standard C++ smart pointers
can interfere with BaseObject’s own cleanup mechanisms
(explicit delete, delete-on-GC and delete-on-cleanup).

Introducing custom smart pointers allows referring to `BaseObject`s
safely while keeping those mechanisms intact.

PR-URL: #141
Reviewed-By: James M Snell <[email protected]>
jasnell pushed a commit that referenced this pull request Oct 2, 2019
jasnell pushed a commit that referenced this pull request Oct 3, 2019
Referring to `BaseObject` instances using standard C++ smart pointers
can interfere with BaseObject’s own cleanup mechanisms
(explicit delete, delete-on-GC and delete-on-cleanup).

Introducing custom smart pointers allows referring to `BaseObject`s
safely while keeping those mechanisms intact.

PR-URL: #141
Reviewed-By: James M Snell <[email protected]>
jasnell pushed a commit that referenced this pull request Oct 3, 2019
addaleax added a commit to addaleax/node that referenced this pull request Nov 12, 2019
Referring to `BaseObject` instances using standard C++ smart pointers
can interfere with BaseObject’s own cleanup mechanisms
(explicit delete, delete-on-GC and delete-on-cleanup).

Introducing custom smart pointers allows referring to `BaseObject`s
safely while keeping those mechanisms intact.

Refs: nodejs/quic#141
Refs: nodejs/quic#149
Reviewed-By: James M Snell <[email protected]>
addaleax added a commit to addaleax/node that referenced this pull request Nov 12, 2019
MylesBorins pushed a commit to addaleax/node that referenced this pull request Apr 1, 2020
Referring to `BaseObject` instances using standard C++ smart pointers
can interfere with BaseObject’s own cleanup mechanisms
(explicit delete, delete-on-GC and delete-on-cleanup).

Introducing custom smart pointers allows referring to `BaseObject`s
safely while keeping those mechanisms intact.

Refs: nodejs/quic#141
Refs: nodejs/quic#149
Reviewed-By: James M Snell <[email protected]>

PR-URL: nodejs#30374
Refs: nodejs/quic#165
Reviewed-By: David Carlier <[email protected]>
MylesBorins pushed a commit to addaleax/node that referenced this pull request Apr 1, 2020
MylesBorins pushed a commit to addaleax/node that referenced this pull request Apr 1, 2020
MylesBorins pushed a commit to addaleax/node that referenced this pull request Apr 1, 2020
This is no longer necessary now that the copyable `BaseObjectPtr`
is available (as opposed to the only-movable `v8::Global`).

PR-URL: nodejs#30374
Refs: nodejs/quic#141
Refs: nodejs/quic#149
Refs: nodejs/quic#141
Refs: nodejs/quic#165
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: David Carlier <[email protected]>
MylesBorins pushed a commit to addaleax/node that referenced this pull request Apr 1, 2020
This allows keeping `BaseObjectPtr`s to `HandleWrap` instances.
Previously, the pointer kept the `HandleWrap` object alive, leaving
the Environment cleanup code that waits for the handle list to drain
in a busy loop, because only the `HandleWrap` destructor removed
the item from the list.

Refs: nodejs/quic#165
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Daniel Bevenius <[email protected]>

PR-URL: nodejs#30374
Refs: nodejs/quic#141
Refs: nodejs/quic#149
Refs: nodejs/quic#141
Reviewed-By: David Carlier <[email protected]>
MylesBorins pushed a commit to nodejs/node that referenced this pull request Apr 1, 2020
Referring to `BaseObject` instances using standard C++ smart pointers
can interfere with BaseObject’s own cleanup mechanisms
(explicit delete, delete-on-GC and delete-on-cleanup).

Introducing custom smart pointers allows referring to `BaseObject`s
safely while keeping those mechanisms intact.

Refs: nodejs/quic#141
Refs: nodejs/quic#149
Reviewed-By: James M Snell <[email protected]>

Backport-PR-URL: #32301
PR-URL: #30374
Refs: nodejs/quic#165
Reviewed-By: David Carlier <[email protected]>
MylesBorins pushed a commit to nodejs/node that referenced this pull request Apr 1, 2020
Refs: nodejs/quic#141
Reviewed-By: James M Snell <[email protected]>

Backport-PR-URL: #32301
PR-URL: #30374
Refs: nodejs/quic#149
Refs: nodejs/quic#165
Reviewed-By: David Carlier <[email protected]>
MylesBorins pushed a commit to nodejs/node that referenced this pull request Apr 1, 2020
MylesBorins pushed a commit to nodejs/node that referenced this pull request Apr 1, 2020
This is no longer necessary now that the copyable `BaseObjectPtr`
is available (as opposed to the only-movable `v8::Global`).

Backport-PR-URL: #32301
PR-URL: #30374
Refs: nodejs/quic#141
Refs: nodejs/quic#149
Refs: nodejs/quic#141
Refs: nodejs/quic#165
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: David Carlier <[email protected]>
MylesBorins pushed a commit to nodejs/node that referenced this pull request Apr 1, 2020
This allows keeping `BaseObjectPtr`s to `HandleWrap` instances.
Previously, the pointer kept the `HandleWrap` object alive, leaving
the Environment cleanup code that waits for the handle list to drain
in a busy loop, because only the `HandleWrap` destructor removed
the item from the list.

Refs: nodejs/quic#165
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Daniel Bevenius <[email protected]>

Backport-PR-URL: #32301
PR-URL: #30374
Refs: nodejs/quic#141
Refs: nodejs/quic#149
Refs: nodejs/quic#141
Reviewed-By: David Carlier <[email protected]>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants