diff --git a/src/crypto/crypto_tls.cc b/src/crypto/crypto_tls.cc index 31b7905b72d7f9..1cafa5f48cbbfb 100644 --- a/src/crypto/crypto_tls.cc +++ b/src/crypto/crypto_tls.cc @@ -438,7 +438,9 @@ TLSWrap::TLSWrap(Environment* env, } TLSWrap::~TLSWrap() { - Destroy(); + // Destructors can run from V8 weak callbacks during garbage collection. + // Do not invoke JS-visible write callbacks from here. + Destroy(false); } MaybeLocal TLSWrap::ocsp_response() const { @@ -1307,15 +1309,21 @@ void TLSWrap::DestroySSL(const FunctionCallbackInfo& args) { Debug(wrap, "DestroySSL() finished"); } -void TLSWrap::Destroy() { +void TLSWrap::Destroy(bool invoke_queued) { if (!ssl_) return; - // If there is a write happening, mark it as finished. - write_callback_scheduled_ = true; + if (invoke_queued) { + // If there is a write happening, mark it as finished. + write_callback_scheduled_ = true; - // And destroy - InvokeQueued(UV_ECANCELED, "Canceled because of SSL destruction"); + // And destroy + InvokeQueued(UV_ECANCELED, "Canceled because of SSL destruction"); + } else { + current_write_.reset(); + current_empty_write_.reset(); + write_callback_scheduled_ = false; + } env()->external_memory_accounter()->Decrease(env()->isolate(), kExternalSize); ssl_.reset(); diff --git a/src/crypto/crypto_tls.h b/src/crypto/crypto_tls.h index 87063b50bb7455..0a0d8ebfeaed58 100644 --- a/src/crypto/crypto_tls.h +++ b/src/crypto/crypto_tls.h @@ -159,7 +159,7 @@ class TLSWrap : public AsyncWrap, void EncOut(); // Write encrypted data from enc_out_ to underlying stream. void ClearIn(); // SSL_write() clear data "in" to SSL. void ClearOut(); // SSL_read() clear text "out" from SSL. - void Destroy(); + void Destroy(bool invoke_queued = true); // Call Done() on outstanding WriteWrap request. void InvokeQueued(int status, const char* error_str = nullptr);