diff options
Diffstat (limited to 'create_lz.cc')
-rw-r--r-- | create_lz.cc | 83 |
1 files changed, 43 insertions, 40 deletions
diff --git a/create_lz.cc b/create_lz.cc index 9cfdedd..a6a7146 100644 --- a/create_lz.cc +++ b/create_lz.cc @@ -1,18 +1,18 @@ -/* Tarlz - Archiver with multimember lzip compression - Copyright (C) 2013-2019 Antonio Diaz Diaz. +/* Tarlz - Archiver with multimember lzip compression + Copyright (C) 2013-2020 Antonio Diaz Diaz. - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ #define _FILE_OFFSET_BITS 64 @@ -39,9 +39,10 @@ namespace { +const Cl_options * gcl_opts = 0; // local vars needed by add_member_lz enum { max_packet_size = 1 << 20 }; class Packet_courier; -Packet_courier * courierp = 0; // local vars needed by add_member_lz +Packet_courier * courierp = 0; unsigned long long partial_data_size = 0; // size of current block @@ -156,7 +157,7 @@ public: If filename.empty() (end of lzip member token), move to next queue. */ void receive_packet( const Ipacket * const ipacket ) { - if( ipacket->filename.size() ) + if( !ipacket->filename.empty() ) slot_tally.get_slot(); // wait for a free slot xlock( &imutex ); ipacket_queues[receive_worker_id].push( ipacket ); @@ -184,7 +185,7 @@ public: } xunlock( &imutex ); if( ipacket ) - { if( ipacket->filename.size() ) slot_tally.leave_slot(); } + { if( !ipacket->filename.empty() ) slot_tally.leave_slot(); } else { // notify muxer when last worker exits @@ -270,13 +271,13 @@ int add_member_lz( const char * const filename, const struct stat *, if( !fill_headers( filename, *extended, header, file_size, flag ) ) { delete[] header; delete extended; return 0; } - if( solidity == bsolid && + if( gcl_opts->solidity == bsolid && block_is_full( *extended, file_size, partial_data_size ) ) courierp->receive_packet( new Ipacket ); // end of group courierp->receive_packet( new Ipacket( filename, file_size, extended, header ) ); - if( solidity == no_solid ) // one tar member per group + if( gcl_opts->solidity == no_solid ) // one tar member per group courierp->receive_packet( new Ipacket ); if( verbosity >= 1 ) std::fprintf( stderr, "%s\n", filename ); return 0; @@ -285,31 +286,30 @@ int add_member_lz( const char * const filename, const struct stat *, struct Grouper_arg { + const Cl_options * cl_opts; Packet_courier * courier; - const Arg_parser * parser; - bool dereference; }; /* Package metadata of the files to be archived and pass them to the - courier for distribution to workers. */ + courier for distribution to workers. +*/ extern "C" void * grouper( void * arg ) { const Grouper_arg & tmp = *(const Grouper_arg *)arg; + const Cl_options & cl_opts = *tmp.cl_opts; Packet_courier & courier = *tmp.courier; - const Arg_parser & parser = *tmp.parser; - const bool dereference = tmp.dereference; - for( int i = 0; i < parser.arguments(); ++i ) // parse command line + for( int i = 0; i < cl_opts.parser.arguments(); ++i ) // parse command line { - const int code = parser.code( i ); - const std::string & arg = parser.argument( i ); + const int code = cl_opts.parser.code( i ); + const std::string & arg = cl_opts.parser.argument( i ); const char * filename = arg.c_str(); if( code == 'C' && chdir( filename ) != 0 ) { show_file_error( filename, "Error changing working directory", errno ); cleanup_and_fail(); } if( code ) continue; // skip options - if( parser.argument( i ).empty() ) continue; // skip empty names + if( cl_opts.parser.argument( i ).empty() ) continue; // skip empty names std::string deslashed; // arg without trailing slashes unsigned len = arg.size(); while( len > 1 && arg[len-1] == '/' ) --len; @@ -321,13 +321,13 @@ extern "C" void * grouper( void * arg ) { show_file_error( filename, "Can't stat input file", errno ); set_error_status( 1 ); } else if( nftw( filename, add_member_lz, 16, - dereference ? 0 : FTW_PHYS ) != 0 ) - cleanup_and_fail(); // write error or oom - else if( solidity == dsolid ) // end of group + cl_opts.dereference ? 0 : FTW_PHYS ) != 0 ) + cleanup_and_fail(); // write error or OOM + else if( cl_opts.solidity == dsolid ) // end of group courier.receive_packet( new Ipacket ); } - if( solidity == bsolid && partial_data_size ) // finish last block + if( cl_opts.solidity == bsolid && partial_data_size ) // finish last block { partial_data_size = 0; courierp->receive_packet( new Ipacket ); } courier.finish(); // no more packets to send return 0; @@ -336,7 +336,8 @@ extern "C" void * grouper( void * arg ) /* Writes ibuf to encoder. To minimize dictionary size, it does not read from encoder until encoder's input buffer is full or finish is true. - Sends opacket to courier and allocates new obuf each time obuf is full. */ + Sends opacket to courier and allocates new obuf each time obuf is full. +*/ void loop_encode( const uint8_t * const ibuf, const int isize, uint8_t * & obuf, int & opos, Packet_courier & courier, LZ_Encoder * const encoder, const int worker_id, @@ -395,7 +396,8 @@ struct Worker_arg /* Get ipackets from courier, compress headers and file data, and give the - opackets produced to courier. */ + opackets produced to courier. +*/ extern "C" void * cworker( void * arg ) { const Worker_arg & tmp = *(const Worker_arg *)arg; @@ -502,7 +504,8 @@ extern "C" void * cworker( void * arg ) /* Get from courier the processed and sorted packets, and write - their contents to the output archive. */ + their contents to the output archive. +*/ void muxer( Packet_courier & courier, const int outfd ) { while( true ) @@ -521,24 +524,24 @@ void muxer( Packet_courier & courier, const int outfd ) // init the courier, then start the grouper and the workers and call the muxer -int encode_lz( const char * const archive_namep, const Arg_parser & parser, +int encode_lz( const Cl_options & cl_opts, const char * const archive_namep, const int dictionary_size, const int match_len_limit, - const int num_workers, const int outfd, const int out_slots, - const int debug_level, const bool dereference ) + const int outfd ) { const int in_slots = 65536; // max small files (<=512B) in 64 MiB + const int num_workers = cl_opts.num_workers; const int total_in_slots = ( INT_MAX / num_workers >= in_slots ) ? num_workers * in_slots : INT_MAX; + gcl_opts = &cl_opts; /* If an error happens after any threads have been started, exit must be called before courier goes out of scope. */ - Packet_courier courier( num_workers, total_in_slots, out_slots ); + Packet_courier courier( num_workers, total_in_slots, cl_opts.out_slots ); courierp = &courier; // needed by add_member_lz Grouper_arg grouper_arg; + grouper_arg.cl_opts = &cl_opts; grouper_arg.courier = &courier; - grouper_arg.parser = &parser; - grouper_arg.dereference = dereference; pthread_t grouper_thread; int errcode = pthread_create( &grouper_thread, 0, grouper, &grouper_arg ); @@ -582,7 +585,7 @@ int encode_lz( const char * const archive_namep, const Arg_parser & parser, { show_file_error( archive_namep, "Error closing archive", errno ); retval = 1; } - if( debug_level & 1 ) + if( cl_opts.debug_level & 1 ) std::fprintf( stderr, "any worker tried to consume from grouper %8u times\n" "any worker had to wait %8u times\n" |