Listing 1 qjob
#!/bin/ksh
# qjob. Listing 1
# qjob and semaphore are both in /usr/local/bin,
# so make sure /usr/local/bin/ is in the PATH.
PATH="$PATH:/usr/local/bin"
# Return Codes
SUCCESS=0
COMMAND_RETURNED_NON_ZERO=1
CLONES_ALREADY_QUEUED=2
MISSING_COMMAND=3
QUEUE_SHUT_DOWN=4
# The queue_job Function
queue_job()
{
# Imagine $job_name has walked into a bank called $queue_name.
# Customers at the $queue_name bank must queue up in one line.
# The bank has $num_tellers teller windows. $job_name wants to
# submit a request called $command. If $num_clones > 1, then
# the theme to the Twilight Zone is playing in the background.
local job_name=$1
local queue_name=$2
local num_tellers=$3
local num_clones=$4
local command="$5"
if semaphore -t 0 -I $num_clones -P ${job_name}_already_queued
then
# If there are NOT $num_clones instances of $job_name already running
# or waiting in line, then $job_name grabs a resource and gets in line.
if semaphore -q -s 10 -I $num_tellers -P $queue_name
then
# When a teller is free, $job_name executes.
if [[ ${DEBUG} = TRUE ]]
then
echo "Now serving job ${job_name} from queue ${queue_name}."
fi
$command
command_return_code=$?
# $job_name releases the resource so another instance of $job_name
# can use it.
semaphore -V ${job_name}_already_queued
# $job_name walks away so his teller can service someone else.
semaphore -V $queue_name
if (( $command_return_code == 0 ))
then
# $job_name's request appears to have been fulfilled.
return $SUCCESS
else
return $COMMAND_RETURNED_NON_ZERO
fi
else
# Sorry, the bank just closed.
# $job_name throws away his number and goes home empty handed.
semaphore -V ${job_name}_already_queued
if [[ ${DEBUG} = TRUE ]]
then
echo "Job ${job_name} didn't reach the head of queue \
${queue_name}."
fi
return $QUEUE_SHUT_DOWN
fi
else
if [[ ${DEBUG} = TRUE ]]
then
echo "Can't put job ${job_name} in queue ${queue_name}."
if (( $num_clones <= 0 ))
then
echo "Job ${job_name} is not allowed\c"
elif (( $num_clones == 1 ))
then
echo "$num_clones instance of job ${job_name} is waiting\c"
else
echo "$num_clones instances of job ${job_name} are waiting\c"
fi
echo " in queue ${queue_name}."
fi
return $CLONES_ALREADY_QUEUED
fi
}
# Variables
local job_name=""
local queue_name=""
local command=""
integer num_clones=1
integer num_tellers=1
DEBUG=FALSE
# Get the command line options.
while getopts c:dj:n:q: option
do
case $option in
d) DEBUG=TRUE ;;
c) num_clones=$OPTARG ;;
j) job_name=$OPTARG ;;
n) num_tellers=$OPTARG ;;
q) queue_name=$OPTARG ;;
esac
done
shift $(($OPTIND-1))
# Get the command including any arguements.
command="$@"
# Generate some default values.
if [[ -z $job_name ]]
then
job_name=$(basename $1)
fi
if [[ -z $queue_name ]]
then
queue_name=default_queue
fi
# Verify that a command was specified, and queue the job.
if [[ -n "$command" ]]
then
queue_job $job_name $queue_name $num_tellers $num_clones "$command"
return $?
else
return $MISSING_COMMAND
fi
|