Here's a solution using only ubiquitous shell tools.

This should be easily done by forking the slow process and a `sleep` in the background and waiting for the first to finish, except that the `wait` shell builtin waits for *all* jobs to finish rather than only for the first one.

So instead, fork the slow process and a `sleep` in the background, have them both report their status through a pipe, and read the first status that comes out of the pipe.

 fifo=$(mktemp -u)
 mkfifo "$fifo"
 { ./slowprocess.sh; echo z >$fifo; } &
 payload_pgid=$!
 { sleep 3; echo a >$fifo; } &
 sleep_pgid=$!
 read status <$fifo
 case $status in
 a) echo "That process is taking a long time"; read ignored <$fifo;;
 z) echo "Done already"; kill -INT -$sleep_pgid;;
 esac
 rm "$fifo"