From c936709e28d97b777a2b12ac8471b64bcb72aa7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?= <grubba@grubba.org> Date: Tue, 9 Feb 2016 14:11:28 +0100 Subject: [PATCH] Filesystem.Monitor: Improved robustness. It seems ADT.Heap()->peek() sometimes can index the NULL value (cf [bug 7644]). The most likely cause is that the last element of the heap was removed by a different thread during the call. Inhibit propagation of the error to the caller. Work around for [bug 7644]. --- .../Filesystem.pmod/Monitor.pmod/basic.pike | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/lib/modules/Filesystem.pmod/Monitor.pmod/basic.pike b/lib/modules/Filesystem.pmod/Monitor.pmod/basic.pike index ded753a2a9..ab891b5d77 100644 --- a/lib/modules/Filesystem.pmod/Monitor.pmod/basic.pike +++ b/lib/modules/Filesystem.pmod/Monitor.pmod/basic.pike @@ -1490,19 +1490,28 @@ int check(int|void max_wait, int|void max_cnt, int cnt; int t = time(); if (sizeof(monitor_queue)) { - Monitor m; - while ((m = monitor_queue->peek()) && (m->next_poll <= t)) { - cnt += check_monitor(m); - if (!(--scan_cnt)) { - m = monitor_queue->peek(); - break; - } - } - if (m) { - ret = m->next_poll - t; - if (ret <= 0) ret = 1; - } else { - scan_cnt--; + // NB: peek() can apparently in some circumstances throw errors. + // cf [bug 7644]. The likely cause being that a different + // thread removed the last element during the call. Make + // sure not to propagate the error to the caller. + mixed err = catch { + Monitor m; + while ((m = monitor_queue->peek()) && (m->next_poll <= t)) { + cnt += check_monitor(m); + if (!(--scan_cnt)) { + m = monitor_queue->peek(); + break; + } + } + if (m) { + ret = m->next_poll - t; + if (ret <= 0) ret = 1; + } else { + scan_cnt--; + } + }; + if (err) { + master()->handle_error(err); } } if (cnt || !scan_wait || !scan_cnt) { -- GitLab