diff options
Diffstat (limited to 'src/install-pkglist.c')
-rw-r--r-- | src/install-pkglist.c | 162 |
1 files changed, 153 insertions, 9 deletions
diff --git a/src/install-pkglist.c b/src/install-pkglist.c index 7e0cc00..26e00e9 100644 --- a/src/install-pkglist.c +++ b/src/install-pkglist.c @@ -70,7 +70,8 @@ #include <defs.h> -#define WAIT_USEC_FOR_CHILD 10000 +#define START_USEC_FOR_CHILD 30000 +#define WAIT_USEC_FOR_CHILD 10000 char *program = PROGRAM_NAME; char *root = NULL, *srcdir = NULL, *pkglist_fname = NULL, @@ -933,6 +934,31 @@ void get_args( int argc, char *argv[] ) FATAL_ERROR( "Defined --root '%s' is not a directory", buf ); } + len = strlen( (const char *)buf ); + + (void)strcat( buf, PACKAGES_PATH ); + if( _mkdir_p( buf, S_IRWXU | S_IRWXG | S_IRWXO ) != 0 ) + { + FATAL_ERROR( "Cannot access '/%s' directory", PACKAGES_PATH ); + } + + /********************************************* + Create other directories of Setup Database: + */ + buf[len] = '\0'; + (void)strcat( buf, REMOVED_PKGS_PATH ); + if( _mkdir_p( buf, S_IRWXU | S_IRWXG | S_IRWXO ) != 0 ) + { + FATAL_ERROR( "Cannot access '/%s' directory", REMOVED_PKGS_PATH ); + } + + buf[len] = '\0'; + (void)strcat( buf, SETUP_PATH ); + if( _mkdir_p( buf, S_IRWXU | S_IRWXG | S_IRWXO ) != 0 ) + { + FATAL_ERROR( "Cannot access '/%s' directory", SETUP_PATH ); + } + free( buf ); } /* @@ -1652,7 +1678,7 @@ static void install_package( struct package *package ) if( gpgck ) (void)sprintf( opt, "--gpg-verify " ); if( (install_mode != CONSOLE) && !parallel && !progress ) (void)strcat( opt, "--info-dialog " ); - if( parallel ) (void)strcat( opt, "--ignore-chrefs-errors " ); + if( parallel ) (void)strcat( opt, "--disable-chrefs " ); if( (install_mode == CONSOLE) && !parallel && !progress ) out = " "; cmd = (char *)malloc( (size_t)PATH_MAX ); @@ -1728,27 +1754,112 @@ static void serial_install_packages( void ) } } +static int __install_count( void ) +{ + struct dlist *list = packages, *next = NULL; + int ret = 0; + + while( list ) + { + struct package *package = NULL; + + next = dlist_next( list ); + package = (struct package *)list->data; + if( package && !strncmp( "install", strproc( package->procedure ), 7 ) ) + { + ++ret; + } + list = next; + } + + return ret; +} + +static int __update_count( void ) +{ + struct dlist *list = packages, *next = NULL; + int ret = 0; + + while( list ) + { + struct package *package = NULL; + + next = dlist_next( list ); + package = (struct package *)list->data; + if( package && !strncmp( "update", strproc( package->procedure ), 6 ) ) + { + ++ret; + } + list = next; + } + + return ret; +} + +static int __nstreams( void ) +{ + int ret = 1; + int nprocs = get_nprocs(); + + if( nprocs > 4 ) + { + ret = nprocs / 2; + } + + return ret; +} static void *install_process( void *args ) { struct dlist *list = packages, *next = NULL; - int nstreams = ncpus * 2; /* two concurents for CPU */ + int nstreams = __nstreams(); + + /********************************************* + install packages with procedure == install: + */ + while( list ) + { + struct package *package = NULL; + + next = dlist_next( list ); + package = (struct package *)list->data; + if( package && !strncmp( "install", strproc( package->procedure ), 7 ) ) + { + install_package( package ); + } + list = next; + + /* wait for available CPU: */ + while( (__child - __terminated) > nstreams ) usleep( START_USEC_FOR_CHILD ); + } + + return NULL; +} + +static void *update_process( void *args ) +{ + struct dlist *list = packages, *next = NULL; + + int nstreams = __nstreams(); + /********************************************* + install packages with procedure == update: + */ while( list ) { struct package *package = NULL; next = dlist_next( list ); package = (struct package *)list->data; - if( package ) + if( package && !strncmp( "update", strproc( package->procedure ), 6 ) ) { install_package( package ); } list = next; /* wait for available CPU: */ - while( (__child - __terminated) > nstreams ) usleep( WAIT_USEC_FOR_CHILD ); + while( (__child - __terminated) > nstreams ) usleep( START_USEC_FOR_CHILD ); } return NULL; @@ -1768,6 +1879,20 @@ static void parallel_install_packages( void ) (void)pthread_detach( install_process_id ); } +static void parallel_update_packages( void ) +{ + pthread_t install_process_id; + int status; + + /* Start the parallel installation process: */ + status = pthread_create( &install_process_id, NULL, update_process, NULL ); + if( status != 0 ) + { + FATAL_ERROR( "Cannot start parallel installation process" ); + } + (void)pthread_detach( install_process_id ); +} + /* End of install functions. *********************************************/ @@ -1939,6 +2064,8 @@ int main( int argc, char *argv[] ) parallel installation: */ int percent = 0; + int __all_install = __install_count(); + int __all_update = __update_count(); __all = dlist_length( packages ); __done = 0; __child = 0; @@ -1947,10 +2074,28 @@ int main( int argc, char *argv[] ) show_progress(); + /********************************************* + install packages with procedure == install: + */ parallel_install_packages(); - if( __terminated < __all ) + while( !__done ) { + percent = ( __terminated < __all ) ? __terminated * 100 / __all : 100; + + update_progress( percent ); + usleep( WAIT_USEC_FOR_CHILD ); + } + + __done = 0; __child = 0; + + if( __all_update ) + { + /********************************************* + install packages with procedure == update: + */ + parallel_update_packages(); + while( !__done ) { percent = ( __terminated < __all ) ? __terminated * 100 / __all : 100; @@ -1958,9 +2103,9 @@ int main( int argc, char *argv[] ) update_progress( percent ); usleep( WAIT_USEC_FOR_CHILD ); } - } - __done = 0; __child = 0; + __done = 0; __child = 0; + } stop_progress(); @@ -2025,7 +2170,6 @@ int main( int argc, char *argv[] ) } - if( tmpdir ) { _rm_tmpdir( (const char *)tmpdir ); free( tmpdir ); } free_resources(); |