@@ -139,8 +139,8 @@ class ZlibContext : public MemoryRetainer {
139139 CompressionError ResetStream ();
140140
141141 // Zlib-specific:
142- CompressionError Init (int level, int window_bits, int mem_level, int strategy,
143- std::vector<unsigned char >&& dictionary);
142+ void Init (int level, int window_bits, int mem_level, int strategy,
143+ std::vector<unsigned char >&& dictionary);
144144 void SetAllocationFunctions (alloc_func alloc, free_func free, void * opaque);
145145 CompressionError SetParams (int level, int strategy);
146146
@@ -157,7 +157,10 @@ class ZlibContext : public MemoryRetainer {
157157 private:
158158 CompressionError ErrorForMessage (const char * message) const ;
159159 CompressionError SetDictionary ();
160+ bool InitZlib ();
160161
162+ Mutex mutex_; // Protects zlib_init_done_.
163+ bool zlib_init_done_ = false ;
161164 int err_ = 0 ;
162165 int flush_ = 0 ;
163166 int level_ = 0 ;
@@ -615,13 +618,8 @@ class ZlibStream : public CompressionStream<ZlibContext> {
615618 AllocScope alloc_scope (wrap);
616619 wrap->context ()->SetAllocationFunctions (
617620 AllocForZlib, FreeForZlib, static_cast <CompressionStream*>(wrap));
618- const CompressionError err =
619- wrap->context ()->Init (level, window_bits, mem_level, strategy,
620- std::move (dictionary));
621- if (err.IsError ())
622- wrap->EmitError (err);
623-
624- return args.GetReturnValue ().Set (!err.IsError ());
621+ wrap->context ()->Init (level, window_bits, mem_level, strategy,
622+ std::move (dictionary));
625623 }
626624
627625 static void Params (const FunctionCallbackInfo<Value>& args) {
@@ -724,6 +722,15 @@ using BrotliEncoderStream = BrotliCompressionStream<BrotliEncoderContext>;
724722using BrotliDecoderStream = BrotliCompressionStream<BrotliDecoderContext>;
725723
726724void ZlibContext::Close () {
725+ {
726+ Mutex::ScopedLock lock (mutex_);
727+ if (!zlib_init_done_) {
728+ dictionary_.clear ();
729+ mode_ = NONE;
730+ return ;
731+ }
732+ }
733+
727734 CHECK_LE (mode_, UNZIP);
728735
729736 int status = Z_OK;
@@ -742,6 +749,11 @@ void ZlibContext::Close() {
742749
743750
744751void ZlibContext::DoThreadPoolWork () {
752+ bool first_init_call = InitZlib ();
753+ if (first_init_call && err_ != Z_OK) {
754+ return ;
755+ }
756+
745757 const Bytef* next_expected_header_byte = nullptr ;
746758
747759 // If the avail_out is left at 0, then it means that it ran out
@@ -897,6 +909,11 @@ CompressionError ZlibContext::GetErrorInfo() const {
897909
898910
899911CompressionError ZlibContext::ResetStream () {
912+ bool first_init_call = InitZlib ();
913+ if (first_init_call && err_ != Z_OK) {
914+ return ErrorForMessage (" Failed to init stream before reset" );
915+ }
916+
900917 err_ = Z_OK;
901918
902919 switch (mode_) {
@@ -930,7 +947,7 @@ void ZlibContext::SetAllocationFunctions(alloc_func alloc,
930947}
931948
932949
933- CompressionError ZlibContext::Init (
950+ void ZlibContext::Init (
934951 int level, int window_bits, int mem_level, int strategy,
935952 std::vector<unsigned char >&& dictionary) {
936953 if (!((window_bits == 0 ) &&
@@ -974,6 +991,15 @@ CompressionError ZlibContext::Init(
974991 window_bits_ *= -1 ;
975992 }
976993
994+ dictionary_ = std::move (dictionary);
995+ }
996+
997+ bool ZlibContext::InitZlib () {
998+ Mutex::ScopedLock lock (mutex_);
999+ if (zlib_init_done_) {
1000+ return false ;
1001+ }
1002+
9771003 switch (mode_) {
9781004 case DEFLATE:
9791005 case GZIP:
@@ -995,15 +1021,15 @@ CompressionError ZlibContext::Init(
9951021 UNREACHABLE ();
9961022 }
9971023
998- dictionary_ = std::move (dictionary);
999-
10001024 if (err_ != Z_OK) {
10011025 dictionary_.clear ();
10021026 mode_ = NONE;
1003- return ErrorForMessage ( " zlib error " ) ;
1027+ return true ;
10041028 }
10051029
1006- return SetDictionary ();
1030+ SetDictionary ();
1031+ zlib_init_done_ = true ;
1032+ return true ;
10071033}
10081034
10091035
@@ -1040,6 +1066,11 @@ CompressionError ZlibContext::SetDictionary() {
10401066
10411067
10421068CompressionError ZlibContext::SetParams (int level, int strategy) {
1069+ bool first_init_call = InitZlib ();
1070+ if (first_init_call && err_ != Z_OK) {
1071+ return ErrorForMessage (" Failed to init stream before set parameters" );
1072+ }
1073+
10431074 err_ = Z_OK;
10441075
10451076 switch (mode_) {
0 commit comments