Commit 75c42e9d108 for nodejs
commit 75c42e9d1085a1c5ad9009b531a7aa16bdf00c79
Author: Yagiz Nizipli <yagiz@nizipli.com>
Date: Wed Oct 28 17:25:03 2026 -0400
crypto: skip clearing empty OpenSSL error queues
ClearErrorOnReturn calls ERR_clear_error() when it is created and
again when it goes out of scope. That function resets all 16 slots of
the thread's error queue, including two free() calls per slot, even
when the queue is empty, which is almost always the case. Check for a
queued error first, which costs a fraction of that.
ClearErrorOnReturn guards most crypto operations, including every
CryptoJob, so this applies to all of them.
Signed-off-by: Yagiz Nizipli <yagiz@nizipli.com>
Assisted-by: Grok
PR-URL: https://github.com/nodejs/node/pull/67109
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
diff --git a/deps/ncrypto/ncrypto.cc b/deps/ncrypto/ncrypto.cc
index 51f09e42710..ba0e1f2e09d 100644
--- a/deps/ncrypto/ncrypto.cc
+++ b/deps/ncrypto/ncrypto.cc
@@ -337,14 +337,22 @@ constexpr BoringSSLCipher kBoringSSLCiphers[] = {
// ============================================================================
+namespace {
+// ERR_clear_error() resets every slot of the error queue even when it is
+// empty, which costs several times more than checking for an error first.
+void ClearErrorQueue() {
+ if (ERR_peek_error() != 0) ERR_clear_error();
+}
+} // namespace
+
ClearErrorOnReturn::ClearErrorOnReturn(CryptoErrorList* errors)
: errors_(errors) {
- ERR_clear_error();
+ ClearErrorQueue();
}
ClearErrorOnReturn::~ClearErrorOnReturn() {
if (errors_ != nullptr) errors_->capture();
- ERR_clear_error();
+ ClearErrorQueue();
}
unsigned long ClearErrorOnReturn::peekError() { // NOLINT(runtime/int)