-
Notifications
You must be signed in to change notification settings - Fork 0
/
bgpid.sh
75 lines (69 loc) · 1.75 KB
/
bgpid.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#!/usr/bin/env bash
# shellcheck disable=2128
bg_init() {
[[ -n $BASHPID ]] || { printf "bgpid.sh: \$BASHPID is not set" >&2; return 1; }
if [[ -z $BG_PIDS || $BG_PIDS_OWNER != "$BASHPID" ]]; then
BG_PIDS_OWNER=$BASHPID
BG_PIDS=()
fi
}
bg_add() {
bg_init || return $?
BG_PIDS+=("$1")
bg_block "${BG_MAXPARALLEL:-4}" || return $?
}
bg_run() {
bg_block "${BG_MAXPARALLEL:-4}" || return $?
"$@" & BG_PIDS+=($!)
}
bg_killall() {
[[ $BG_PIDS_OWNER = "$BASHPID" ]] || return 0
[[ ${#BG_PIDS[@]} -eq 0 ]] || kill -"${1:-TERM}" "${BG_PIDS[@]}" 2>/dev/null || true
while [[ ${#BG_PIDS[@]} -gt 0 ]]; do
bg_waitany || true
done
return 0
}
# shellcheck disable=2120
bg_block() {
bg_init || return $?
local max=${1:-0}
[[ $max -ne -1 ]] || return 0
local ret=0
while [[ ${#BG_PIDS[@]} -ne 0 && ${#BG_PIDS[@]} -ge $max ]]; do
bg_waitany || { ret=$?; break; }
done
if [[ $ret -gt 0 ]]; then
if [[ -n $BG_SIGNAL ]]; then
[[ ${#BG_PIDS[@]} -eq 0 ]] || kill -"$BG_SIGNAL" "${BG_PIDS[@]}" 2>/dev/null || true
fi
while [[ ${#BG_PIDS[@]} -gt 0 ]]; do
bg_waitany || true
done
fi
return $ret
}
bg_waitany() {
[[ $BG_PIDS_OWNER = "$BASHPID" ]] || return 0
local pid found=false ret=0 bg_new_pids=()
local original_opts=$-; set +x
while [[ ${#BG_PIDS[@]} -gt 0 ]]; do
for pid in "${BG_PIDS[@]}"; do
if ! $found && ! kill -0 "$pid" 2>/dev/null; then
[[ $original_opts != *x* ]] || set -x
wait "$pid" 2>/dev/null || ret=$?
found=true
else
bg_new_pids+=("$pid")
fi
done
if $found; then
BG_PIDS=("${bg_new_pids[@]}")
return $ret
else
bg_new_pids=()
sleep "${BG_POLLRATE:-0.05}"
fi
done
[[ $original_opts != *x* ]] || set -x
}