From 59036f4d824cc9dc6b50981050ae15b6dd4df651 Mon Sep 17 00:00:00 2001 From: Tim Starling Date: Thu, 19 Feb 2009 07:15:19 +0000 Subject: [PATCH] Basic multiprocess operation via pcntl_fork() --- maintenance/runJobs.php | 68 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/maintenance/runJobs.php b/maintenance/runJobs.php index e2a589544b..ee6d0dc11c 100644 --- a/maintenance/runJobs.php +++ b/maintenance/runJobs.php @@ -10,10 +10,72 @@ * @ingroup Maintenance */ -$optionsWithArgs = array( 'maxjobs', 'type' ); +$optionsWithArgs = array( 'maxjobs', 'type', 'procs' ); $wgUseNormalUser = true; require_once( 'commandLine.inc' ); +if ( isset( $options['procs'] ) ) { + $procs = intval( $options['procs'] ); + if ( $procs < 1 || $procs > 1000 ) { + echo "Invalid argument to --procs\n"; + exit( 1 ); + } + + // Don't share DB or memcached connections + $lb = wfGetLB(); + $lb->closeAll(); + $wgCaches = array(); + unset( $wgMemc ); + + // Spawn the children + $children = array(); + for ( $childId = 0; $childId < $procs; $childId++ ) { + $pid = pcntl_fork(); + if ( $pid === -1 || $pid === false ) { + echo "Error creating child processes\n"; + exit( 1 ); + } + if ( !$pid ) { + break; + } + + $children[] = $pid; + } + if ( $pid ) { + // Parent process + // Trap SIGTERM + pcntl_signal( SIGTERM, 'handleTermSignal', false ); + // Wait for a child to exit + $status = false; + $termReceived = false; + do { + $deadPid = pcntl_wait( $status ); + // Run signal handlers + if ( function_exists( 'pcntl_signal_dispatch' ) ) { + pcntl_signal_dispatch(); + } else { + declare (ticks=1) { $status = $status; } + } + } while ( $deadPid == -1 && !$termReceived ); + // Kill the remaining children + // If they're already dead, say due to SIGTERM, then they'll be zombies until + // pcntl_waitpid() below, so the PID won't be reused. + foreach ( $children as $childPid ) { + if ( $childPid != $deadPid ) { + posix_kill( $childPid, SIGTERM ); + } + } + foreach ( $children as $childPid ) { + pcntl_waitpid( $childPid, $status ); + } + // All done + exit( 0 ); + } + + // Set up this child + $wgMemc = wfGetCache( $wgMainCacheType ); +} + if ( isset( $options['maxjobs'] ) ) { $maxJobs = $options['maxjobs']; } else { @@ -65,3 +127,7 @@ function runJobsLog( $msg ) { wfDebugLog( 'runJobs', $msg ); } +function handleTermSignal( $signal ) { + $GLOBALS['termReceived'] = true; +} + -- 2.20.1