Skip to content
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
fixup! worker: improve integration with native addons
  • Loading branch information
addaleax committed Feb 20, 2019
commit 9c0f9d3dbd31ad1316e1849e69e0f9de6336f980
28 changes: 23 additions & 5 deletions src/node_binding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "env-inl.h"
#include "node_native_module.h"
#include "util.h"
#include <atomic>

#if HAVE_OPENSSL
#define NODE_BUILTIN_OPENSSL_MODULES(V) V(crypto) V(tls_wrap)
Expand Down Expand Up @@ -207,6 +208,19 @@ void* wrapped_dlsym(void* handle, const char* symbol) {

#endif // _AIX

#ifdef __linux__
static bool libc_may_be_musl() {
static std::atomic_bool retval; // Cache the return value.
static std::atomic_bool has_cached_retval { false };
if (has_cached_retval) return retval;
retval = dlsym(RTLD_DEFAULT, "gnu_get_libc_version") == nullptr;
has_cached_retval = true;
return retval;
}
#else // __linux__
static bool libc_may_be_musl() { return false; }
#endif // __linux__

namespace node {

using v8::Context;
Expand Down Expand Up @@ -310,14 +324,18 @@ bool DLib::Open() {

void DLib::Close() {
if (handle_ == nullptr) return;
int err = dlclose(handle_);

if (err == 0) {
// musl libc implements dlclose() as a no-op which returns 1.
if (libc_may_be_musl()) {
// musl libc implements dlclose() as a no-op which returns 0.
// As a consequence, trying to re-load a previously closed addon at a later
// point will not call its static constructors, which Node.js uses.
// Therefore, when dlclose() fails, we assume that the shared object
// still exists and keep it in our handle map.
// Therefore, when we may be using musl libc, we assume that the shared
// object exists indefinitely and keep it in our handle map.
return;
}

int err = dlclose(handle_);
if (err == 0) {
if (has_entry_in_global_handle_map_)
global_handle_map.erase(handle_);
}
Expand Down