#!/bin/bash # Copyright 1999-2012 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # For routines we want to use in ebuild-helpers/ but don't want to # expose to the general ebuild environment. source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh # # API functions for doing parallel processing # numjobs() { # Copied from eutils.eclass:makeopts_jobs() local jobs=$(echo " ${MAKEOPTS} " | \ sed -r -n 's:.*[[:space:]](-j|--jobs[=[:space:]])[[:space:]]*([0-9]+).*:\2:p') echo ${jobs:-1} } multijob_init() { # Setup a pipe for children to write their pids to when they finish. mj_control_pipe=$(mktemp -t multijob.XXXXXX) rm "${mj_control_pipe}" mkfifo "${mj_control_pipe}" exec {mj_control_fd}<>${mj_control_pipe} rm -f "${mj_control_pipe}" # See how many children we can fork based on the user's settings. mj_max_jobs=$(numjobs) mj_num_jobs=0 } multijob_child_init() { trap 'echo ${BASHPID} $? >&'${mj_control_fd} EXIT trap 'exit 1' INT TERM } multijob_finish_one() { local pid ret read -r -u ${mj_control_fd} pid ret : $(( --mj_num_jobs )) return ${ret} } multijob_finish() { local ret=0 while [[ ${mj_num_jobs} -gt 0 ]] ; do multijob_finish_one : $(( ret |= $? )) done # Let bash clean up its internal child tracking state. wait return ${ret} } multijob_post_fork() { : $(( ++mj_num_jobs )) if [[ ${mj_num_jobs} -ge ${mj_max_jobs} ]] ; then multijob_finish_one fi return $? }