diff options
author | Andrey Pechkurov <apechkurov@gmail.com> | 2020-06-23 17:18:31 +0300 |
---|---|---|
committer | Andrey Pechkurov <apechkurov@gmail.com> | 2020-07-22 16:20:33 +0300 |
commit | f8eaeb0c8e3196eb9d2ec8fd818c36aa27e31f72 (patch) | |
tree | b796efa6c3032dd466c72dcb77d772e912aa0f9b /src/node_zlib.cc | |
parent | b0b52b2023f5cd0df4ae921850815586b4313dca (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.cc | 59 |
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_) { |