Start locking

master
Garrett Mills 3 years ago
parent 65af602dd4
commit e5e2d2e780
No known key found for this signature in database
GPG Key ID: 35F6925363BCE548

@ -12,7 +12,7 @@ export PS4='+(${BASH_SOURCE##*/}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
export g__EXISTS=true
g__PATH="${BASH_SOURCE[0]}"
g__CALLER_PATH="${BASH_SOURCE[1]}"
g__CALLER_PATH="${BASH_SOURCE[1]:-shell}"
# The global logging level. Lower the number, higher the priority.
g__LOGGING_LEVEL=2
@ -64,6 +64,12 @@ g__APP_LAST_ARGPARSE=''
g__APP_LAST_ALIAS=''
g__LOCKING_FILE_DIR="/tmp"
g__LOCKING_NAME_X_DESCRIPTOR=()
g__LOCKING_NEXT_DESCRIPTOR=100
##
# Initialize the framework
@ -92,6 +98,8 @@ function g::internals::cleanup() {
for file in "${g__FILES_TO_CLEANUP[@]}"; do
rm -rf "$file"
done
g::lock::cleanupForExit
}
@ -1982,14 +1990,89 @@ function g::flag::has() {
return $(g::app::command::parse::has::flag "$nameOrPosition" "$uuid")
}
# logging/debug flags
g::log::all # TODO remove
function g::lock::file() {
local callerName="$(basename "$g__CALLER_PATH")"
local name="${1:-$callerName}"
g::internal "Resolving lock file path for name: $name" g::lock
g::path::resolve "$g__LOCKING_FILE_DIR" "${name}.lock"
}
function g::arr::assoc::hasKey() {
local key="$1"
shift
local array="$@"
for possibleKey in "${!array[@]}"; do
if [[ "$key" == "$possibleKey" ]]; then
return $(g::util::true)
fi
done
return $(g::util::false)
}
function g::lock::descriptor() {
local callerName="$(basename "$g__CALLER_PATH")"
local name="${1:-$callerName}"
local file="$(g::lock::file "$name")"
g::internal "Resolving lock file descriptor for file: $file" g::lock
if g::arr::assoc::hasKey "$name" "${g__LOCKING_NAME_X_DESCRIPTOR[@]}"; then
printf $fd
return $(g::util::true)
fi
local fd=$g__LOCKING_NEXT_DESCRIPTOR
g__LOCKING_NEXT_DESCRIPTOR=$(($g__LOCKING_NEXT_DESCRIPTOR + 1))
g__LOCKING_NAME_X_DESCRIPTOR+=( ["$name"]=$fd )
g::internal "Mapped FD $fd to lock file: $file" g::lock
exec $fd>"$file" || return $(g::util::false)
printf $fd
}
function g::lock::acquire() {
local callerName="$(basename "$g__CALLER_PATH")"
local name="${1:-$callerName}"
local descriptor=$(g::lock::descriptor "$name")
flock $descriptor || g::error::throw "Unable to acquire lock: ${name} (${descriptor})"
}
function g::lock::try() {
local callerName="$(basename "$g__CALLER_PATH")"
local name="${1:-$callerName}"
local descriptor=$(g::lock::descriptor "$name")
g::internal "Got descriptor for lock: ${descriptor}"
flock -n $descriptor || return $(g::util::false)
return $(g::util::true)
}
function g::lock::release() {
local callerName="$(basename "$g__CALLER_PATH")"
local name="${1:-$callerName}"
local file=$(g::lock::file "$name")
rm -rf "$file"
}
function g::lock::cleanupForExit() {
for file in "${!g__LOCKING_NAME_X_DESCRIPTOR[@]}"; do
rm -rf "$file"
done
}
# dependency declarations
# output helpers
# argument parsing
# exception handling
# JSON parsing, INI parsing, rich data types (named parameters & arrays/maps)

Loading…
Cancel
Save