Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Pechkurov <apechkurov@gmail.com>2020-06-23 17:18:31 +0300
committerAndrey Pechkurov <apechkurov@gmail.com>2020-07-22 16:20:33 +0300
commitf8eaeb0c8e3196eb9d2ec8fd818c36aa27e31f72 (patch)
treeb796efa6c3032dd466c72dcb77d772e912aa0f9b /src/node_zlib.cc
parentb0b52b2023f5cd0df4ae921850815586b4313dca (diff)
zlib: switch to lazy init for zlib streams
PR-URL: https://github.com/nodejs/node/pull/34048 Reviewed-By: Anna Henningsen <anna@addaleax.net>
Diffstat (limited to 'src/node_zlib.cc')
-rw-r--r--src/node_zlib.cc59
1 files changed, 45 insertions, 14 deletions
diff --git a/src/node_zlib.cc b/src/node_zlib.cc
index 85e87327c07..efb11debf8f 100644
--- a/src/node_zlib.cc
+++ b/src/node_zlib.cc
@@ -139,8 +139,8 @@ class ZlibContext : public MemoryRetainer {
CompressionError ResetStream();
// Zlib-specific:
- CompressionError Init(int level, int window_bits, int mem_level, int strategy,
- std::vector<unsigned char>&& dictionary);
+ void Init(int level, int window_bits, int mem_level, int strategy,
+ std::vector<unsigned char>&& dictionary);
void SetAllocationFunctions(alloc_func alloc, free_func free, void* opaque);
CompressionError SetParams(int level, int strategy);
@@ -157,7 +157,10 @@ class ZlibContext : public MemoryRetainer {
private:
CompressionError ErrorForMessage(const char* message) const;
CompressionError SetDictionary();
+ bool InitZlib();
+ Mutex mutex_; // Protects zlib_init_done_.
+ bool zlib_init_done_ = false;
int err_ = 0;
int flush_ = 0;
int level_ = 0;
@@ -615,13 +618,8 @@ class ZlibStream : public CompressionStream<ZlibContext> {
AllocScope alloc_scope(wrap);
wrap->context()->SetAllocationFunctions(
AllocForZlib, FreeForZlib, static_cast<CompressionStream*>(wrap));
- const CompressionError err =
- wrap->context()->Init(level, window_bits, mem_level, strategy,
- std::move(dictionary));
- if (err.IsError())
- wrap->EmitError(err);
-
- return args.GetReturnValue().Set(!err.IsError());
+ wrap->context()->Init(level, window_bits, mem_level, strategy,
+ std::move(dictionary));
}
static void Params(const FunctionCallbackInfo<Value>& args) {
@@ -724,6 +722,15 @@ using BrotliEncoderStream = BrotliCompressionStream<BrotliEncoderContext>;
using BrotliDecoderStream = BrotliCompressionStream<BrotliDecoderContext>;
void ZlibContext::Close() {
+ {
+ Mutex::ScopedLock lock(mutex_);
+ if (!zlib_init_done_) {
+ dictionary_.clear();
+ mode_ = NONE;
+ return;
+ }
+ }
+
CHECK_LE(mode_, UNZIP);
int status = Z_OK;
@@ -742,6 +749,11 @@ void ZlibContext::Close() {
void ZlibContext::DoThreadPoolWork() {
+ bool first_init_call = InitZlib();
+ if (first_init_call && err_ != Z_OK) {
+ return;
+ }
+
const Bytef* next_expected_header_byte = nullptr;
// If the avail_out is left at 0, then it means that it ran out
@@ -897,6 +909,11 @@ CompressionError ZlibContext::GetErrorInfo() const {
CompressionError ZlibContext::ResetStream() {
+ bool first_init_call = InitZlib();
+ if (first_init_call && err_ != Z_OK) {
+ return ErrorForMessage("Failed to init stream before reset");
+ }
+
err_ = Z_OK;
switch (mode_) {
@@ -930,7 +947,7 @@ void ZlibContext::SetAllocationFunctions(alloc_func alloc,
}
-CompressionError ZlibContext::Init(
+void ZlibContext::Init(
int level, int window_bits, int mem_level, int strategy,
std::vector<unsigned char>&& dictionary) {
if (!((window_bits == 0) &&
@@ -974,6 +991,15 @@ CompressionError ZlibContext::Init(
window_bits_ *= -1;
}
+ dictionary_ = std::move(dictionary);
+}
+
+bool ZlibContext::InitZlib() {
+ Mutex::ScopedLock lock(mutex_);
+ if (zlib_init_done_) {
+ return false;
+ }
+
switch (mode_) {
case DEFLATE:
case GZIP:
@@ -995,15 +1021,15 @@ CompressionError ZlibContext::Init(
UNREACHABLE();
}
- dictionary_ = std::move(dictionary);
-
if (err_ != Z_OK) {
dictionary_.clear();
mode_ = NONE;
- return ErrorForMessage("zlib error");
+ return true;
}
- return SetDictionary();
+ SetDictionary();
+ zlib_init_done_ = true;
+ return true;
}
@@ -1040,6 +1066,11 @@ CompressionError ZlibContext::SetDictionary() {
CompressionError ZlibContext::SetParams(int level, int strategy) {
+ bool first_init_call = InitZlib();
+ if (first_init_call && err_ != Z_OK) {
+ return ErrorForMessage("Failed to init stream before set parameters");
+ }
+
err_ = Z_OK;
switch (mode_) {