#!/usr/bin/bash
# Author: Theodore Zacharia
# V0.1: 25/06/2022 - Initial Release
#
# This script provides a template to start all other scripts with
# supports arguments being passed and multi-threaded functions
# Uses shell builtin function getopts
#
# For the thread limiting to work you must call this as follows:
# sh myscript.sh 
# or
# bash myscript.sh
#

# *** Globals
TRACE=0
MYARG=""
MAXTHREADS=20   # max number of concurrent threads to allow
SLEEPTIME=3     # time in seconds to wait when max number of threads running


# *** Functions
_usage()
{
	echo "usage: $0 [-h] [-t] [-M maxthreads] [-a arg] positional_params"
	echo "where"
	cat <<- _EOF_
	  -h        Displays this help message
	  -t        Set trace on
	  -M count  Sets the max concurrent threads
_EOF_
}

_mymultithreadedfunc()
{
    read -r this_pid < /proc/self/stat
    echo "running func $$ / ${this_pid%% *} with $@" >&2
    sleep 5
    echo "${this_pid%% *} done" >&2
}


# *** Mainline
THISSCRIPT=${0#./*}

# process input parameters
while getopts tha:M: AOPT
do
case $AOPT in
	t) TRACE=1 ;; # set TRACE mode
	a) MYARG=$OPTARG ;;
	M) MAXTHREADS=$OPTARG ;;
	h) _usage
	   exit 1 ;;
	*) echo "$AOPT is an invalid option" >&2
	   exit 2 ;;
esac
done

shift $((OPTIND-1))

if [ $TRACE -gt 0 ]
then
	echo "Starting at $(date)"
	echo "TRACE=$TRACE" >&2
	echo "MYARG=$MYARG" >&2
	echo "positional_args=$@" >&2
fi

DOSOMETHING=0

while [ $DOSOMETHING -lt 100 ]
do
    DOSOMETHING=$(expr $DOSOMETHING + 1)
    THREADS=$(ps -ef | grep -v grep | grep -c $THISSCRIPT)
    if [ $TRACE -gt 0 ] ; then echo "THREADS=$THREADS at DOSOMETHING=$DOSOMETHING" >&2 ; fi
    while [ $THREADS -ge $MAXTHREADS ]
    do
        echo "waiting in $$ with $THREADS threads" >&2
        sleep $SLEEPTIME
        THREADS=$(ps -ef | grep -v grep | grep -c $THISSCRIPT)
    done

    {
    _mymultithreadedfunc hello at $(date)
    } &
done
