@@ -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 ;
@@ -614,13 +617,8 @@ class ZlibStream : public CompressionStream<ZlibContext> {
614
617
AllocScope alloc_scope (wrap);
615
618
wrap->context ()->SetAllocationFunctions (
616
619
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));
624
622
}
625
623
626
624
static void Params (const FunctionCallbackInfo<Value>& args) {
@@ -723,6 +721,15 @@ using BrotliEncoderStream = BrotliCompressionStream<BrotliEncoderContext>;
723
721
using BrotliDecoderStream = BrotliCompressionStream<BrotliDecoderContext>;
724
722
725
723
void ZlibContext::Close () {
724
+ {
725
+ Mutex::ScopedLock lock (mutex_);
726
+ if (!zlib_init_done_) {
727
+ dictionary_.clear ();
728
+ mode_ = NONE;
729
+ return ;
730
+ }
731
+ }
732
+
726
733
CHECK_LE (mode_, UNZIP);
727
734
728
735
int status = Z_OK;
@@ -741,6 +748,11 @@ void ZlibContext::Close() {
741
748
742
749
743
750
void ZlibContext::DoThreadPoolWork () {
751
+ bool first_init_call = InitZlib ();
752
+ if (first_init_call && err_ != Z_OK) {
753
+ return ;
754
+ }
755
+
744
756
const Bytef* next_expected_header_byte = nullptr ;
745
757
746
758
// If the avail_out is left at 0, then it means that it ran out
@@ -896,6 +908,11 @@ CompressionError ZlibContext::GetErrorInfo() const {
896
908
897
909
898
910
CompressionError 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
+
899
916
err_ = Z_OK;
900
917
901
918
switch (mode_) {
@@ -929,7 +946,7 @@ void ZlibContext::SetAllocationFunctions(alloc_func alloc,
929
946
}
930
947
931
948
932
- CompressionError ZlibContext::Init (
949
+ void ZlibContext::Init (
933
950
int level, int window_bits, int mem_level, int strategy,
934
951
std::vector<unsigned char >&& dictionary) {
935
952
if (!((window_bits == 0 ) &&
@@ -973,6 +990,15 @@ CompressionError ZlibContext::Init(
973
990
window_bits_ *= -1 ;
974
991
}
975
992
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
+
976
1002
switch (mode_) {
977
1003
case DEFLATE:
978
1004
case GZIP:
@@ -994,15 +1020,15 @@ CompressionError ZlibContext::Init(
994
1020
UNREACHABLE ();
995
1021
}
996
1022
997
- dictionary_ = std::move (dictionary);
998
-
999
1023
if (err_ != Z_OK) {
1000
1024
dictionary_.clear ();
1001
1025
mode_ = NONE;
1002
- return ErrorForMessage ( " zlib error " ) ;
1026
+ return true ;
1003
1027
}
1004
1028
1005
- return SetDictionary ();
1029
+ SetDictionary ();
1030
+ zlib_init_done_ = true ;
1031
+ return true ;
1006
1032
}
1007
1033
1008
1034
@@ -1039,6 +1065,11 @@ CompressionError ZlibContext::SetDictionary() {
1039
1065
1040
1066
1041
1067
CompressionError 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
+
1042
1073
err_ = Z_OK;
1043
1074
1044
1075
switch (mode_) {
0 commit comments