@@ -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 ;
@@ -614,13 +617,8 @@ class ZlibStream : public CompressionStream<ZlibContext> {
614617 AllocScope alloc_scope (wrap);
615618 wrap->context ()->SetAllocationFunctions (
616619 AllocForZlib, FreeForZlib, static_cast <CompressionStream*>(wrap));
617- const CompressionError err =
618- wrap->context ()->Init (level, window_bits, mem_level, strategy,
619- std::move (dictionary));
620- if (err.IsError ())
621- wrap->EmitError (err);
622-
623- return args.GetReturnValue ().Set (!err.IsError ());
620+ wrap->context ()->Init (level, window_bits, mem_level, strategy,
621+ std::move (dictionary));
624622 }
625623
626624 static void Params (const FunctionCallbackInfo<Value>& args) {
@@ -723,6 +721,15 @@ using BrotliEncoderStream = BrotliCompressionStream<BrotliEncoderContext>;
723721using BrotliDecoderStream = BrotliCompressionStream<BrotliDecoderContext>;
724722
725723void ZlibContext::Close () {
724+ {
725+ Mutex::ScopedLock lock (mutex_);
726+ if (!zlib_init_done_) {
727+ dictionary_.clear ();
728+ mode_ = NONE;
729+ return ;
730+ }
731+ }
732+
726733 CHECK_LE (mode_, UNZIP);
727734
728735 int status = Z_OK;
@@ -741,6 +748,11 @@ void ZlibContext::Close() {
741748
742749
743750void ZlibContext::DoThreadPoolWork () {
751+ bool first_init_call = InitZlib ();
752+ if (first_init_call && err_ != Z_OK) {
753+ return ;
754+ }
755+
744756 const Bytef* next_expected_header_byte = nullptr ;
745757
746758 // If the avail_out is left at 0, then it means that it ran out
@@ -896,6 +908,11 @@ CompressionError ZlibContext::GetErrorInfo() const {
896908
897909
898910CompressionError ZlibContext::ResetStream () {
911+ bool first_init_call = InitZlib ();
912+ if (first_init_call && err_ != Z_OK) {
913+ return ErrorForMessage (" Failed to init stream before reset" );
914+ }
915+
899916 err_ = Z_OK;
900917
901918 switch (mode_) {
@@ -929,7 +946,7 @@ void ZlibContext::SetAllocationFunctions(alloc_func alloc,
929946}
930947
931948
932- CompressionError ZlibContext::Init (
949+ void ZlibContext::Init (
933950 int level, int window_bits, int mem_level, int strategy,
934951 std::vector<unsigned char >&& dictionary) {
935952 if (!((window_bits == 0 ) &&
@@ -973,6 +990,15 @@ CompressionError ZlibContext::Init(
973990 window_bits_ *= -1 ;
974991 }
975992
993+ dictionary_ = std::move (dictionary);
994+ }
995+
996+ bool ZlibContext::InitZlib () {
997+ Mutex::ScopedLock lock (mutex_);
998+ if (zlib_init_done_) {
999+ return false ;
1000+ }
1001+
9761002 switch (mode_) {
9771003 case DEFLATE:
9781004 case GZIP:
@@ -994,15 +1020,15 @@ CompressionError ZlibContext::Init(
9941020 UNREACHABLE ();
9951021 }
9961022
997- dictionary_ = std::move (dictionary);
998-
9991023 if (err_ != Z_OK) {
10001024 dictionary_.clear ();
10011025 mode_ = NONE;
1002- return ErrorForMessage ( " zlib error " ) ;
1026+ return true ;
10031027 }
10041028
1005- return SetDictionary ();
1029+ SetDictionary ();
1030+ zlib_init_done_ = true ;
1031+ return true ;
10061032}
10071033
10081034
@@ -1039,6 +1065,11 @@ CompressionError ZlibContext::SetDictionary() {
10391065
10401066
10411067CompressionError ZlibContext::SetParams (int level, int strategy) {
1068+ bool first_init_call = InitZlib ();
1069+ if (first_init_call && err_ != Z_OK) {
1070+ return ErrorForMessage (" Failed to init stream before set parameters" );
1071+ }
1072+
10421073 err_ = Z_OK;
10431074
10441075 switch (mode_) {
0 commit comments