- #!/usr/bin/ksh93
- # should work for ksh88/ksh93/bash4
- ########################################################################
- # #
- # This software is part of the ast package #
- # Copyright (c) 2019 Roland Mainz #
- # and is licensed under the #
- # Eclipse Public License, Version 1.0 #
- # by AT&T Intellectual Property #
- # #
- # A copy of the License is available at #
- # http://www.eclipse.org/org/documents/epl-v10.html #
- # (with md5 checksum b35adb5213ca9657e911e9befb180842) #
- # #
- # #
- # Roland Mainz <roland.mainz@nrubsig.org> #
- # #
- ########################################################################
- #
- # Copyright (c) 2019, Roland Mainz. All rights reserved.
- #
- #
- # shsemaphore.sh - wait until <n> customers are waiting
- # at the semaphore
- #
- # Usage:
- # 1. init semaphore ("mysemaname" is the 'semaphore address')
- # $ shsemaphore.sh init mysemaname
- #
- # 2. let two semaphore customers (names are 'Bear' and 'Fox')
- # wait for each other:
- # $ shsemaphore.sh wait mysemaname Bear 2 &
- # $ shsemaphore.sh wait mysemaname Fox 2
- #
- # 3. Cleanup all the mess if you are really done:
- # $ shsemaphore.sh cleanup mysemaname
- #
- # POSIX path for mkdir, ls, rm, rmdir ...
- export PATH='/bin:/usr/bin'
- # constants
- typeset -r SEMA_BASE_DIR='/tmp/'
- # arguments
- typeset sema_cmd="$1"
- typeset sema_address="${SEMA_BASE_DIR}/shsemaphore_$2"
- typeset sema_name="${sema_address}/$3"
- typeset -i sema_count="$4"
- # Debug:
- #printf "cmd=%s, address=%s, name=%s, count=%d\n" \
- # "${sema_cmd}" "${sema_address}" "${sema_name}" "${sema_count}"
- function sema_cleanup
- {
- rm -Rf "${sema_address}"
- }
- function sema_init
- {
- if [[ -z "$SEMA_BASE_DIR" || -z "$sema_address" ]] ; then
- printf "%s: Illegal arguments.\n" "$0" 1>&2
- return 1
- fi
- mkdir -p "${SEMA_BASE_DIR}"
- sema_cleanup
- mkdir "${sema_address}"
- }
- function sema_wait
- {
- typeset IFS
- if [[ -z "$SEMA_BASE_DIR" || -z "$sema_address" || -z "$sema_name" || -z "$sema_count" ]] ; then
- printf "%s: Illegal arguments.\n" "$0" 1>&2
- return 1
- fi
- if ! mkdir "${sema_name}" ; then
- printf "%s: Count not set name.\n" "$0" 1>&2
- return 1
- fi
- # is semaphore still valid ?
- cd "${sema_address}" || return 4
- IFS=$'\n'
- while (( 1 )) ; do
- # 1. we rely on shell globing to avoid |fork()|/|exec()|
- # for ls(1)
- # 2. we count '.' and '..', too. Both special dirs
- # will disappear if the directory "${sema_address}"
- # gets removed
- sfiles=( $(printf "%s\n" */ .*/ 2>'/dev/null') )
- # Debug:
- #printf 'sfiles=|%s| ' "${sfiles[@]}" ; printf '\n'
- # semaphore condition fullfilled ?
- (( ${#sfiles[@]} >= (sema_count+2) )) && return 0
- # semaphore gone ?
- # In that case we get only two entries from globbing
- # above, one for '*/' and one for '.*/'
- (( ${#sfiles[@]} <= 2 )) && return 4
- sleep 2
- done
- # notreached
- }
- # main
- case "${sema_cmd}" in
- 'init')
- sema_init
- exit $?
- ;;
- 'wait')
- sema_wait
- exit $?
- ;;
- 'cleanup')
- sema_cleanup
- exit $?
- ;;
- *)
- printf "%s: Unknown command.\n" "$0" 1>&1
- exit 1
- ;;
- esac
semaphore implemented as shell script (version without |fork()|/|exec()| per test cycle)
Posted by Anonymous on Mon 18th Nov 2019 17:45
raw | new post
modification of post by Anonymous (view diff)
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.