1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4# map[(scope_id,track,cleanup_id) -> cleanup_command] 5# track={d=default | p=priority} 6declare -A __DEFER__JOBS 7 8# map[(scope_id,track) -> # cleanup_commands] 9declare -A __DEFER__NJOBS 10 11# scope_id of the topmost scope. 12__DEFER__SCOPE_ID=0 13 14__defer__ndefer_key() 15{ 16 local track=$1; shift 17 18 echo $__DEFER__SCOPE_ID,$track 19} 20 21__defer__defer_key() 22{ 23 local track=$1; shift 24 local defer_ix=$1; shift 25 26 echo $__DEFER__SCOPE_ID,$track,$defer_ix 27} 28 29__defer__ndefers() 30{ 31 local track=$1; shift 32 33 echo ${__DEFER__NJOBS[$(__defer__ndefer_key $track)]} 34} 35 36__defer__run() 37{ 38 local track=$1; shift 39 local defer_ix=$1; shift 40 local defer_key=$(__defer__defer_key $track $defer_ix) 41 42 ${__DEFER__JOBS[$defer_key]} 43 unset __DEFER__JOBS[$defer_key] 44} 45 46__defer__schedule() 47{ 48 local track=$1; shift 49 local ndefers=$(__defer__ndefers $track) 50 local ndefers_key=$(__defer__ndefer_key $track) 51 local defer_key=$(__defer__defer_key $track $ndefers) 52 local defer="$@" 53 54 __DEFER__JOBS[$defer_key]="$defer" 55 __DEFER__NJOBS[$ndefers_key]=$((ndefers + 1)) 56} 57 58__defer__scope_wipe() 59{ 60 __DEFER__NJOBS[$(__defer__ndefer_key d)]=0 61 __DEFER__NJOBS[$(__defer__ndefer_key p)]=0 62} 63 64defer_scope_push() 65{ 66 ((__DEFER__SCOPE_ID++)) 67 __defer__scope_wipe 68} 69 70defer_scope_pop() 71{ 72 local defer_ix 73 74 for ((defer_ix=$(__defer__ndefers p); defer_ix-->0; )); do 75 __defer__run p $defer_ix 76 done 77 78 for ((defer_ix=$(__defer__ndefers d); defer_ix-->0; )); do 79 __defer__run d $defer_ix 80 done 81 82 __defer__scope_wipe 83 ((__DEFER__SCOPE_ID--)) 84} 85 86defer() 87{ 88 __defer__schedule d "$@" 89} 90 91defer_prio() 92{ 93 __defer__schedule p "$@" 94} 95 96defer_scopes_cleanup() 97{ 98 while ((__DEFER__SCOPE_ID >= 0)); do 99 defer_scope_pop 100 done 101} 102 103in_defer_scope() 104{ 105 local ret 106 107 defer_scope_push 108 "$@" 109 ret=$? 110 defer_scope_pop 111 112 return $ret 113} 114 115__defer__scope_wipe 116