diff --git a/lib/core-complete.sh b/lib/core-complete.sh index ec07d4c3..5dc8ac8a 100644 --- a/lib/core-complete.sh +++ b/lib/core-complete.sh @@ -5946,11 +5946,8 @@ function ble/complete/auto-menu.idle { [[ $_ble_edit_str ]] || return 0 # bleopt_complete_auto_delay だけ経過してから処理 - local rest_delay=$((bleopt_complete_auto_menu-ble_util_idle_elapsed)) - if ((rest_delay>0)); then - ble/util/idle.sleep "$rest_delay" - return 0 - fi + local until=$((_idle_clock_start+bleopt_complete_auto_menu)) + ble/util/idle.sleep-until "$until" checked && return 0 ble/widget/complete show_menu:no-empty:no-bell } diff --git a/memo/ChangeLog.md b/memo/ChangeLog.md index a8433fdd..4648205b 100644 --- a/memo/ChangeLog.md +++ b/memo/ChangeLog.md @@ -136,6 +136,7 @@ - edit (brackated-paste): fix incomplete `CR => LF` conversion (reported by alborotogarcia) `#D1587` 8d6da16 - main (adjust-bash-options): adjust `LC_COLLATE=C` `#D1588` e87ac21 - highlight (`layer:region`): fix blocked lower-layer changes without selection changes `#D1596` 0000000 +- complete (`auto-menu`): fix sleep loops by clock/sclock difference `#D1597` 0000000 ## Compatibility diff --git a/note.txt b/note.txt index 8dcb243f..7f01aca3 100644 --- a/note.txt +++ b/note.txt @@ -4691,6 +4691,48 @@ bash_tips Done (実装ログ) ------------------------------------------------------------------------------- +2021-06-10 + + * auto-menu: ubuntu20 で auto-menu を有効にしても動いたり動かなかったりである [#D1597] + + auto-menu の起動条件 (直前の widget) に対する判定で失敗しているのだろうか。 + 或いはもっと別の要因だろうか。うーん。或いは idle.sleep に失敗しているとい + う可能性もあるのかもしれない。 + + どうやら ble_util_idle_elapsed が常に 0 になってしまって時間が経過しない + という事で無限ループになっている様子だ。調べると _ble_util_idle_sclock が + 0 の儘で全く動いていない。_ble_util_idle_sclock は ble/util/idle/.sleep + によって増える手筈になっている。ble/util/idle/.sleep は .sleep-until-next + から呼び出される事になっているが、この関数の振る舞いを見るとどうやら + sleep_amount が微妙に負になっている。現在時刻と次のタスクをする時刻を比較 + しているが、次のタスクを実行する時刻が何故か現在時刻よりも前の時刻になっ + てしまっている。 + + 現在時刻は ble/util/idle.clock で取得されていて内部的には ble/util/clock + になっている。ble/util/clock は中で EPOCHREALTIME を参照している。一方で + 次の時刻 _idle_next_time は何処から来るのかというと task の SXXXX という + エントリーから読み出される。この SXXXX というエントリーは + ble/util/idle.sleep で設定されていて、その関数の中で ble/util/idle.clock + が呼び出されている。整理すると + + 1 最初に ble/util/idle.sleep が呼び出されてその時の時刻を元にして待ち時刻 + が設定される。何らかの処理がなされてその回のループが終了する。 + + 2 次のループに入る前に次の待ち時刻まで sleep する。しかし、この時迄に時刻 + が経過して次の待ち時刻を超えてしまうので、スリープ無しで次のループが始 + まる。 + + 3 再び auto-menu.idle が開始するが auto-menu.idle は合計 sleep 時間を使っ + て経過時刻を確認する。然し、実際には sleep は行われていないので + auto-menu.idle は時間が経過していないと勘違いして再び sleep を設定して + 抜ける。 + + 此処での問題は auto-menu.idle は絶対時刻による待ちを設定しているのにも関 + わらず、判定及び残り sleep 時間の算出に sclock つまり sleep 合計時間を使っ + ている事である。どちらかに統一するべきである。裏で重い処理が走っていよう + ともそれはユーザーには見えないのでできるだけ定刻通りに処理を開始するべき + であると思うと、絶対時刻を使用する方に揃えるべきである。 + 2021-06-09 * 2020-09-07 complete: メニュー絞り込みの着色が残ったままになってしまう事がある [#D1596] diff --git a/src/util.sh b/src/util.sh index 63405e87..804c7965 100644 --- a/src/util.sh +++ b/src/util.sh @@ -4584,8 +4584,9 @@ if ((_ble_bash>=40000)); then ble/util/idle.clock/.initialize ble/util/idle.clock/.restart - - local _idle_start=$_ble_util_idle_sclock + ble/util/idle.clock + local _idle_clock_start=$ret + local _idle_sclock_start=$_ble_util_idle_sclock local _idle_is_first=1 local _idle_processed= while :; do @@ -4637,7 +4638,7 @@ if ((_ble_bash>=40000)); then function ble/util/idle.do/.call-task { local _command=$1 local ble_util_idle_status= - local ble_util_idle_elapsed=$((_ble_util_idle_sclock-_idle_start)) + local ble_util_idle_elapsed=$((_ble_util_idle_sclock-_idle_sclock_start)) builtin eval -- "$_command"; local ext=$? if ((ext==148)); then _ble_util_idle_task[_idle_key]=R$_ble_util_idle_SEP$_command @@ -4716,7 +4717,7 @@ if ((_ble_bash>=40000)); then do # Note: 変数 ble_util_idle_elapsed は # $((bleopt_idle_interval)) の評価時に参照される。 - local ble_util_idle_elapsed=$((_ble_util_idle_sclock-_idle_start)) + local ble_util_idle_elapsed=$((_ble_util_idle_sclock-_idle_sclock_start)) local interval=$((bleopt_idle_interval)) if [[ ! $sleep_amount ]] || ((interval=40000)); then [[ ${ble_util_idle_status+set} ]] } function ble/util/idle.sleep { - [[ ${ble_util_idle_status+set} ]] || return 1 + [[ ${ble_util_idle_status+set} ]] || return 2 local ret; ble/util/idle.clock ble_util_idle_status=S$((ret+$1)) } function ble/util/idle.isleep { - [[ ${ble_util_idle_status+set} ]] || return 1 + [[ ${ble_util_idle_status+set} ]] || return 2 ble_util_idle_status=W$((_ble_util_idle_sclock+$1)) } + ## @fn ble/util/idle.sleep-until clock opts + function ble/util/idle.sleep-until { + [[ ${ble_util_idle_status+set} ]] || return 2 + if [[ :$2: == *:checked:* ]]; then + local ret; ble/util/idle.clock + (($1>ret)) || return 1 + fi + ble_util_idle_status=S$1 + } + ## @fn ble/util/idle.isleep-until sclock opts + function ble/util/idle.isleep-until { + [[ ${ble_util_idle_status+set} ]] || return 2 + if [[ :$2: == *:checked:* ]]; then + (($1>_ble_util_idle_sclock)) || return 1 + fi + ble_util_idle_status=W$1 + } function ble/util/idle.wait-user-input { - [[ ${ble_util_idle_status+set} ]] || return 1 + [[ ${ble_util_idle_status+set} ]] || return 2 ble_util_idle_status=I } function ble/util/idle.wait-process { - [[ ${ble_util_idle_status+set} ]] || return 1 + [[ ${ble_util_idle_status+set} ]] || return 2 ble_util_idle_status=P$1 } function ble/util/idle.wait-file-content { - [[ ${ble_util_idle_status+set} ]] || return 1 + [[ ${ble_util_idle_status+set} ]] || return 2 ble_util_idle_status=F$1 } function ble/util/idle.wait-filename { - [[ ${ble_util_idle_status+set} ]] || return 1 + [[ ${ble_util_idle_status+set} ]] || return 2 ble_util_idle_status=E$1 } function ble/util/idle.wait-condition { - [[ ${ble_util_idle_status+set} ]] || return 1 + [[ ${ble_util_idle_status+set} ]] || return 2 ble_util_idle_status=C$1 } function ble/util/idle.continue { - [[ ${ble_util_idle_status+set} ]] || return 1 + [[ ${ble_util_idle_status+set} ]] || return 2 ble_util_idle_status=R }