@@ -784,7 +784,7 @@ void fwriteMain(fwriteMainArgs args)
784784 }
785785
786786 // alloc nth write buffers
787- errno = 0 ;
787+ errno = 0 ;
788788 size_t alloc_size = nth * buffSize ;
789789 if (verbose ) {
790790 DTPRINT (_ ("Allocate %zu bytes (%zu MiB) for buffPool\n" ), alloc_size , alloc_size / MEGA );
@@ -797,39 +797,19 @@ void fwriteMain(fwriteMainArgs args)
797797
798798 // init compress variables
799799#ifndef NOZLIB
800- z_stream * thread_streams = NULL ;
801- char * zbuffPool = NULL ;
800+ z_stream strm ;
801+ char * zbuffPool ;
802802 size_t zbuffSize = 0 ;
803803 size_t compress_len = 0 ;
804804 if (args .is_gzip ) {
805- // alloc zlib streams
806- thread_streams = (z_stream * ) malloc (nth * sizeof (z_stream ));
807- if (!thread_streams ) {
805+ // compute zbuffSize which is the same for each thread
806+ if (init_stream (& strm ) != Z_OK ) {
808807 // # nocov start
809808 free (buffPool );
810- STOP (_ ("Failed to allocated %d bytes for threads_streams." ), (int )(nth * sizeof (z_stream )));
811- // # nocov end
812- }
813- if (verbose ) {
814- DTPRINT (_ ("Allocate %zu bytes for thread_streams\n" ), nth * sizeof (z_stream ));
815- }
816- // VLA on stack should be fine for nth structs; in zlib v1.2.11 sizeof(struct)==112 on 64bit
817- // not declared inside the parallel region because solaris appears to move the struct in
818- // memory when the #pragma omp for is entered, which causes zlib's internal self reference
819- // pointer to mismatch, #4099
820-
821- // compute zbuffSize which is the same for each thread
822- z_stream * stream = thread_streams ;
823- if (init_stream (stream ) != Z_OK ) {
824- // # nocov start
825- free (buffPool );
826- #ifndef NOZLIB
827- free (thread_streams );
828- #endif
829809 STOP (_ ("Can't init stream structure for deflateBound" ));
830810 // # nocov end
831811 }
832- zbuffSize = deflateBound (stream , buffSize );
812+ zbuffSize = deflateBound (& strm , buffSize );
833813 if (verbose )
834814 DTPRINT (_ ("zbuffSize=%d returned from deflateBound\n" ), (int )zbuffSize );
835815
@@ -840,17 +820,18 @@ void fwriteMain(fwriteMainArgs args)
840820 DTPRINT (_ ("Allocate %zu bytes (%zu MiB) for zbuffPool\n" ), alloc_size , alloc_size / MEGA );
841821 }
842822 zbuffPool = malloc (alloc_size );
843- if (! zbuffPool ) {
823+ if (zbuffPool == NULL ) {
844824 // # nocov start
845825 free (buffPool );
846- #ifndef NOZLIB
847- free (thread_streams );
848- #endif
849826 STOP (_ ("Unable to allocate %zu MiB * %d thread compressed buffers; '%d: %s'. Please read ?fwrite for nThread, buffMB and verbose options." ),
850827 zbuffSize / MEGA , nth , errno , strerror (errno ));
851828 // # nocov end
852829 }
830+ } else {
831+ // if no is_gzip, malloc 0 for allowing freeing zbuffPool
832+ zbuffPool = malloc (0 );
853833 }
834+
854835#endif
855836
856837 // write header
@@ -896,17 +877,6 @@ void fwriteMain(fwriteMainArgs args)
896877 int ret0 = 0 , ret1 = 0 , ret2 = 0 ;
897878#ifndef NOZLIB
898879 if (args .is_gzip ) {
899- z_stream * stream = thread_streams ;
900- if (init_stream (stream ) != Z_OK ) {
901- // # nocov start
902- free (buffPool );
903- #ifndef NOZLIB
904- free (thread_streams );
905- free (zbuffPool );
906- #endif
907- STOP (_ ("Can't init stream structure for writing header" ));
908- // # nocov end
909- }
910880 char * zbuff = zbuffPool ;
911881 // write minimal gzip header
912882 char * header = "\037\213\10\0\0\0\0\0\0\3" ;
@@ -917,7 +887,8 @@ void fwriteMain(fwriteMainArgs args)
917887 size_t zbuffUsed = zbuffSize ;
918888 len = (size_t )(ch - buff );
919889 crc = crc32 (crc , (unsigned char * )buff , len );
920- ret1 = compressbuff (stream , zbuff , & zbuffUsed , buff , len );
890+ ret1 = compressbuff (& strm , zbuff , & zbuffUsed , buff , len );
891+ deflateEnd (& strm );
921892 if (ret1 == Z_OK ) {
922893 ret2 = WRITE (f , zbuff , (int )zbuffUsed );
923894 compress_len += zbuffUsed ;
@@ -934,7 +905,6 @@ void fwriteMain(fwriteMainArgs args)
934905 CLOSE (f );
935906 free (buffPool );
936907#ifndef NOZLIB
937- free (thread_streams );
938908 free (zbuffPool );
939909#endif
940910 if (ret0 == -1 ) STOP (_ ("Can't write gzip header error: %d" ), ret0 );
@@ -955,7 +925,6 @@ void fwriteMain(fwriteMainArgs args)
955925 // # nocov start
956926 free (buffPool );
957927#ifndef NOZLIB
958- free (thread_streams );
959928 free (zbuffPool );
960929#endif
961930 STOP (_ ("%s: '%s'" ), strerror (errno ), args .filename );
@@ -984,15 +953,14 @@ void fwriteMain(fwriteMainArgs args)
984953 char * ch = myBuff ;
985954
986955#ifndef NOZLIB
956+ z_stream mystream ;
987957 size_t mylen = 0 ;
988958 int mycrc = 0 ;
989- z_stream * mystream = NULL ;
990959 void * myzBuff = NULL ;
991960 size_t myzbuffUsed = 0 ;
992961 if (args .is_gzip ) {
993- mystream = & thread_streams [me ];
994962 myzBuff = zbuffPool + me * zbuffSize ;
995- if (init_stream (mystream ) != Z_OK ) { // this should be thread safe according to zlib documentation
963+ if (init_stream (& mystream ) != Z_OK ) { // this should be thread safe according to zlib documentation
996964 failed = true; // # nocov
997965 my_failed_compress = -998 ; // # nocov
998966 }
@@ -1040,7 +1008,8 @@ void fwriteMain(fwriteMainArgs args)
10401008 myzbuffUsed = zbuffSize ;
10411009 mylen = (size_t )(ch - myBuff );
10421010 mycrc = crc32 (0 , (unsigned char * )myBuff , mylen );
1043- int ret = compressbuff (mystream , myzBuff , & myzbuffUsed , myBuff , mylen );
1011+ int ret = compressbuff (& mystream , myzBuff , & myzbuffUsed , myBuff , mylen );
1012+ deflateEnd (& mystream );
10441013 if (ret ) {
10451014 failed = true;
10461015 my_failed_compress = ret ;
@@ -1107,18 +1076,12 @@ void fwriteMain(fwriteMainArgs args)
11071076 }
11081077 }
11091078 }
1110- #ifndef NOZLIB
1111- if (args .is_gzip ) {
1112- deflateEnd (mystream );
1113- }
1114- #endif
11151079
11161080 } // end of parallel for loop
11171081
11181082 free (buffPool );
11191083
11201084#ifndef NOZLIB
1121- free (thread_streams );
11221085 free (zbuffPool );
11231086
11241087/* put a 4-byte integer into a byte array in LSB order */
0 commit comments