summaryrefslogtreecommitdiffstats
path: root/create_lz.cc
diff options
context:
space:
mode:
Diffstat (limited to 'create_lz.cc')
-rw-r--r--create_lz.cc83
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"