Implement custom thread local storage for user of library #5601
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
In Node-land, it is super important that we are able to track context across async operations for things like async stack traces and for ensuring that we are attached to the correct v8 context and isolate. One particular pattern for ensuring that a library is leveraging the correct context across a thread pool is by managing thread local storage to track the context as we builds threads.
In LibGit2, because it internally spins up its own threads, it is not possible or easy to build TLS for the internal threads. This means that certain operations that have internal threading in libgit2 (pack building or hopefully someday checkout!), if any callbacks make their way from those internal threads in libgit2, those will not have their TLS initialized to the same context of the thread that requested the libgit2 operation.
Short of providing the ability to do a drop-in replacement for the threading library like libgit2 does allocation, this PR introduces a series of callbacks that will enable a user of the libgit2 library to manage some TLS for internal libgit2 threads for context tracking.
The general flow is for a libgit2 operation to run a callback before initializing a thread internally to provide a calling library an opportunity to seed some TLS on the internally. After a thread is spun up in libgit2, libgit2 will send that pointer back to the user of libgit2 for them to store/set their TLS. Finally, when a thread is exiting in libgit2, we will call a cleanup callback to allow a user of the library to clean up any associated handles.
I've thought long and hard about what's the least disruptive way to allow for this in the library, and this seems like a nice way forward.