Index: src/share/poudriere/common.sh ================================================================== --- src/share/poudriere/common.sh +++ src/share/poudriere/common.sh @@ -6,10 +6,17 @@ RELDATE=$(sysctl kern.osreldate) dir_empty() { find $1 -maxdepth 0 -empty } + +get_freefd() { + # get the higher opended fd + 10 (10 being for safety) + procstat -hf $$ | awk 'function isnum(x){ return(x==x+0) } + isnum($3) && last < $3 { last=$3 } + END { print $3 + 10}' +} err() { if [ $# -ne 2 ]; then err 1 "err expects 2 arguments: exit_number \"message\"" fi @@ -1461,10 +1468,11 @@ } delete_old_pkgs() { [ ! -d ${POUDRIERE}/packages/${MASTERNAME}/All ] && return 0 [ -n "$(dir_empty ${POUDRIERE}/packages/${MASTERNAME}/All)" ] && return 0 + parallel_start for pkg in ${POUDRIERE}/packages/${MASTERNAME}/All/*.${PKG_EXT}; do # Check for non-empty directory with no packages in it [ "${pkg}" = "${POUDRIERE}/packages/${MASTERNAME}/All/*.${PKG_EXT}" ] && break parallel_run "delete_old_pkg ${pkg}" done @@ -1584,46 +1592,38 @@ else echo ${LISTPORTS} | tr ' ' '\n' fi } -parallel_stop() { - wait +parallel_exec() { + eval "$@" + echo >&6 +} + +parallel_start() { + mkfifo ${MASTERMNT}/poudriere/parallel.pipe + exec 6<> ${MASTERMNT}/poudriere/parallel.pipe + rm -f ${MASTERMNT}/poudriere/parallel.pipe + export NBPARALLEL=0 } -_reap_children() { - local skip_count=${1:-0} - PARALLEL_CHILDREN_COUNT=0 - running_jobs=$(jobs -p) # |wc -l here will always be 0 - for pid in ${running_jobs}; do - PARALLEL_CHILDREN_COUNT=$((PARALLEL_CHILDREN_COUNT + 1)) +parallel_stop() { + for j in $(jot ${PARALLEL_JOBS}); do + wait done - [ ${PARALLEL_CHILDREN_COUNT} -lt ${skip_count} ] && return 0 - # No available slot, try to reap some children to find one - for pid in ${running_jobs}; do - if ! kill -0 ${pid} 2>/dev/null; then - wait ${pid} 2>/dev/null || : - PARALLEL_CHILDREN_COUNT=$((PARALLEL_CHILDREN_COUNT - 1)) - fi - done + exec 6<&- + exec 6>&- } parallel_run() { local cmd="$@" - while :; do - _reap_children ${PARALLEL_JOBS} - if [ ${PARALLEL_CHILDREN_COUNT} -lt ${PARALLEL_JOBS} ]; then - # Execute the command in the background - eval "${cmd} &" - return 0 - fi - sleep 0.1 - done + [ ${NBPARALLEL} -eq ${PARALLEL_JOBS} ] && read a <&6 + [ ${NBPARALLEL} -lt ${PARALLEL_JOBS} ] && NBPARALLEL=$((NBPARALLEL + 1)) - return 0 + parallel_exec ${fd} $cmd & } # Get all data that make this build env unique, # so if the same build is done again, # we can use the some of the same cached data @@ -1670,10 +1670,11 @@ :> ${MASTERMNT}/poudriere/ports.ignored :> ${MASTERMNT}/poudriere/ports.skipped build_stats bset status "computingdeps:" + parallel_start for port in $(listed_ports); do [ -d "${MASTERMNT}/usr/ports/${port}" ] || err 1 "Invalid port origin: ${port}" parallel_run "compute_deps ${port}" done parallel_stop