@@ -139,8 +139,8 @@ class ZlibContext : public MemoryRetainer {
139
139
CompressionError ResetStream ();
140
140
141
141
// 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);
144
144
void SetAllocationFunctions (alloc_func alloc, free_func free, void * opaque);
145
145
CompressionError SetParams (int level, int strategy);
146
146
@@ -157,7 +157,10 @@ class ZlibContext : public MemoryRetainer {
157
157
private:
158
158
CompressionError ErrorForMessage (const char * message) const ;
159
159
CompressionError SetDictionary ();
160
+ bool InitZlib ();
160
161
162
+ Mutex mutex_; // Protects zlib_init_done_.
163
+ bool zlib_init_done_ = false ;
161
164
int err_ = 0 ;
162
165
int flush_ = 0 ;
163
166
int level_ = 0 ;
@@ -615,13 +618,8 @@ class ZlibStream : public CompressionStream<ZlibContext> {
615
618
AllocScope alloc_scope (wrap);
616
619
wrap->context ()->SetAllocationFunctions (
617
620
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));
625
623
}
626
624
627
625
static void Params (const FunctionCallbackInfo<Value>& args) {
@@ -724,6 +722,15 @@ using BrotliEncoderStream = BrotliCompressionStream<BrotliEncoderContext>;
724
722
using BrotliDecoderStream = BrotliCompressionStream<BrotliDecoderContext>;
725
723
726
724
void ZlibContext::Close () {
725
+ {
726
+ Mutex::ScopedLock lock (mutex_);
727
+ if (!zlib_init_done_) {
728
+ dictionary_.clear ();
729
+ mode_ = NONE;
730
+ return ;
731
+ }
732
+ }
733
+
727
734
CHECK_LE (mode_, UNZIP);
728
735
729
736
int status = Z_OK;
@@ -742,6 +749,11 @@ void ZlibContext::Close() {
742
749
743
750
744
751
void ZlibContext::DoThreadPoolWork () {
752
+ bool first_init_call = InitZlib ();
753
+ if (first_init_call && err_ != Z_OK) {
754
+ return ;
755
+ }
756
+
745
757
const Bytef* next_expected_header_byte = nullptr ;
746
758
747
759
// If the avail_out is left at 0, then it means that it ran out
@@ -897,6 +909,11 @@ CompressionError ZlibContext::GetErrorInfo() const {
897
909
898
910
899
911
CompressionError 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
+
900
917
err_ = Z_OK;
901
918
902
919
switch (mode_) {
@@ -930,7 +947,7 @@ void ZlibContext::SetAllocationFunctions(alloc_func alloc,
930
947
}
931
948
932
949
933
- CompressionError ZlibContext::Init (
950
+ void ZlibContext::Init (
934
951
int level, int window_bits, int mem_level, int strategy,
935
952
std::vector<unsigned char >&& dictionary) {
936
953
if (!((window_bits == 0 ) &&
@@ -974,6 +991,15 @@ CompressionError ZlibContext::Init(
974
991
window_bits_ *= -1 ;
975
992
}
976
993
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
+
977
1003
switch (mode_) {
978
1004
case DEFLATE:
979
1005
case GZIP:
@@ -995,15 +1021,15 @@ CompressionError ZlibContext::Init(
995
1021
UNREACHABLE ();
996
1022
}
997
1023
998
- dictionary_ = std::move (dictionary);
999
-
1000
1024
if (err_ != Z_OK) {
1001
1025
dictionary_.clear ();
1002
1026
mode_ = NONE;
1003
- return ErrorForMessage ( " zlib error " ) ;
1027
+ return true ;
1004
1028
}
1005
1029
1006
- return SetDictionary ();
1030
+ SetDictionary ();
1031
+ zlib_init_done_ = true ;
1032
+ return true ;
1007
1033
}
1008
1034
1009
1035
@@ -1040,6 +1066,11 @@ CompressionError ZlibContext::SetDictionary() {
1040
1066
1041
1067
1042
1068
CompressionError 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
+
1043
1074
err_ = Z_OK;
1044
1075
1045
1076
switch (mode_) {
0 commit comments