Skip to content

Commit 626583b

Browse files
committed
[indexing] prevent nested rebuilds
1 parent 01d0747 commit 626583b

7 files changed

Lines changed: 73 additions & 32 deletions

File tree

release/loggen.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ def syslog_msgs():
211211
]
212212

213213
COUNTER = 0
214-
while COUNTER < 5000:
214+
while COUNTER < 500000:
215215
loop_inc = datetime.timedelta(seconds=random.weibullvariate(1, 1.5) * 500)
216216
ACCESS_LOG_CURR_TIME += loop_inc
217217
SYSLOG_LOG_CURR_TIME += loop_inc
@@ -230,6 +230,6 @@ def syslog_msgs():
230230
fp.write(next(gen))
231231
# if random.uniform(0.0, 1.0) < 0.010:
232232
# fp.truncate(0)
233-
time.sleep(random.uniform(0.01, 0.02))
233+
time.sleep(random.uniform(0.0001, 0.0002))
234234
# if random.uniform(0.0, 1.0) < 0.001:
235235
# os.remove(fname)

src/base/guard_util.hh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,27 @@ struct guard_helper {
4848
bool gh_enabled{true};
4949
};
5050

51+
struct recursion_preventer : guard_helper {
52+
explicit recursion_preventer(size_t* depth) : rp_depth(depth)
53+
{
54+
*rp_depth += 1;
55+
}
56+
57+
recursion_preventer(const recursion_preventer&) = delete;
58+
recursion_preventer& operator=(const recursion_preventer&) = delete;
59+
recursion_preventer& operator=(recursion_preventer&&) = default;
60+
recursion_preventer(recursion_preventer&&) = default;
61+
62+
~recursion_preventer()
63+
{
64+
if (this->gh_enabled) {
65+
*rp_depth -= 1;
66+
}
67+
}
68+
69+
size_t* rp_depth{nullptr};
70+
};
71+
5172
} // namespace lnav
5273

5374
#endif

src/lnav.cc

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,7 @@ struct refresh_status_bars {
988988
{
989989
static auto* breadcrumb_view = injector::get<breadcrumb_curses*>();
990990
static auto& prompt = lnav::prompt::get();
991+
static auto& exec_phase = injector::get<lnav::exec_phase&>();
991992
static const auto cancel_msg
992993
= lnav::console::user_message::info(
993994
attr_line_t("performing operation, press ")
@@ -1003,33 +1004,33 @@ struct refresh_status_bars {
10031004
}
10041005

10051006
gettimeofday(&current_time, nullptr);
1006-
while (notcurses_get_nblock(this->rsb_screen->get_notcurses(), &ch) > 0)
1007-
{
1008-
lnav_data.ld_user_message_source.clear();
1009-
1010-
alerter::singleton().new_input(ch);
1011-
1012-
lnav_data.ld_input_dispatcher.new_input(
1013-
current_time, this->rsb_screen->get_notcurses(), ch);
1014-
1015-
lnav_data.ld_view_stack.top() | [ch](auto tc) {
1016-
lnav_data.ld_key_repeat_history.update(ch.id, tc->get_top());
1017-
};
1018-
1019-
if (ncinput_ctrl_p(&ch) && ch.id == ']') {
1020-
lnav_data.ld_bottom_source.update_loading(0, 0);
1021-
lnav_data.ld_status[LNS_BOTTOM].set_needs_update();
1022-
retval = lnav::progress_result_t::interrupt;
1023-
}
1007+
auto time_diff = current_time - this->rsb_last_loop_read_time;
1008+
if (to_us(time_diff) > (exec_phase.interactive() ? 100ms : 2s)) {
1009+
while (notcurses_get_nblock(this->rsb_screen->get_notcurses(), &ch)
1010+
> 0)
1011+
{
1012+
lnav_data.ld_user_message_source.clear();
1013+
if ((!exec_phase.interactive() && ch.id == 'q')
1014+
|| (ncinput_ctrl_p(&ch) && ch.id == ']'))
1015+
{
1016+
lnav_data.ld_bottom_source.update_loading(0, 0);
1017+
lnav_data.ld_status[LNS_BOTTOM].set_needs_update();
1018+
retval = lnav::progress_result_t::interrupt;
1019+
} else {
1020+
log_warning(
1021+
"ignoring input while refreshing status bars: %x",
1022+
ch.id);
1023+
}
10241024

1025-
ncinput_free_paste_content(&ch);
1025+
ncinput_free_paste_content(&ch);
10261026

1027-
if (!lnav_data.ld_looping) {
1028-
// No reason to keep processing input after the
1029-
// user has quit. The view stack will also be
1030-
// empty, which will cause issues.
1031-
retval = lnav::progress_result_t::interrupt;
1032-
break;
1027+
if (!lnav_data.ld_looping) {
1028+
// No reason to keep processing input after the
1029+
// user has quit. The view stack will also be
1030+
// empty, which will cause issues.
1031+
retval = lnav::progress_result_t::interrupt;
1032+
break;
1033+
}
10331034
}
10341035
}
10351036

@@ -1084,6 +1085,7 @@ struct refresh_status_bars {
10841085

10851086
screen_curses* rsb_screen;
10861087
std::shared_ptr<top_status_source> rsb_top_source;
1088+
timeval rsb_last_loop_read_time{0};
10871089
};
10881090

10891091
static void
@@ -2274,6 +2276,7 @@ VALUES ('org.lnav.mouse-support', -1, DATETIME('now', '+1 minute'),
22742276
gettimeofday(&current_time, nullptr);
22752277
ui_now = ui_clock::now();
22762278
lb.tick(current_time);
2279+
refresher->rsb_last_loop_read_time = current_time;
22772280

22782281
got_user_input = false;
22792282
if (rc < 0) {

src/lnav.indexing.cc

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,15 @@ rebuild_indexes_result_t
215215
rebuild_indexes(std::optional<ui_clock::time_point> deadline)
216216
{
217217
static auto op = lnav_operation{"rebuild_indexes"};
218-
219218
static auto& exec_phase = injector::get<lnav::exec_phase&>();
219+
thread_local size_t rdepth;
220+
221+
if (rdepth > 0) {
222+
log_warning("skipping nested rebuild");
223+
return {0, false, true};
224+
}
225+
226+
auto recurse_guard = lnav::recursion_preventer{&rdepth};
220227
auto op_guard = lnav_opid_guard::internal(op);
221228

222229
auto& lss = lnav_data.ld_log_source;
@@ -484,6 +491,14 @@ rebuild_indexes(std::optional<ui_clock::time_point> deadline)
484491
void
485492
rebuild_indexes_repeatedly()
486493
{
494+
thread_local size_t rdepth;
495+
496+
if (rdepth > 0) {
497+
log_warning("skipping nested rebuild");
498+
return;
499+
}
500+
501+
auto recurse_guard = lnav::recursion_preventer{&rdepth};
487502
for (size_t attempt = 0; attempt < 50; attempt++) {
488503
auto rebuild_res = rebuild_indexes();
489504
if (!rebuild_res.rir_completed) {

src/lnav_config.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2393,6 +2393,7 @@ reload_config(std::vector<lnav::console::user_message>& errors)
23932393
return;
23942394
}
23952395

2396+
log_error(" property path: %s", path.c_str());
23962397
auto loc_iter
23972398
= lnav_config_locations.find(intern_string::lookup(path));
23982399
auto has_loc = loc_iter != lnav_config_locations.end();

src/logfile.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1781,6 +1781,7 @@ logfile::rebuild_index(std::optional<ui_clock::time_point> deadline)
17811781
this->get_content_size());
17821782

17831783
if (indexing_res == lnav::progress_result_t::interrupt) {
1784+
log_debug("indexing interrupted");
17841785
break;
17851786
}
17861787
}
@@ -2297,16 +2298,16 @@ logfile::message_byte_length(logfile::const_iterator ll, bool include_continues)
22972298
if (retval > 0 && !this->lf_partial_line) {
22982299
retval -= 1;
22992300
}
2301+
require_ge(retval, 0);
23002302
} else {
23012303
retval = next_line->get_offset() - ll->get_offset() - 1;
23022304
if (!include_continues) {
23032305
this->lf_next_line_cache
23042306
= std::make_optional(std::make_pair(ll->get_offset(), retval));
23052307
}
2308+
require_ge(retval, 0);
23062309
}
23072310

2308-
require_ge(retval, 0);
2309-
23102311
return {retval, line_count, meta};
23112312
}
23122313

src/view_curses.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,8 +461,8 @@ view_curses::mvwattrline(ncplane* window,
461461
for (auto iter = sa.cbegin(); iter != sa.cend(); ++iter) {
462462
auto attr_range = iter->sa_range;
463463

464-
require(attr_range.lr_start >= 0);
465-
require(attr_range.lr_end >= -1);
464+
require_ge(attr_range.lr_start, 0);
465+
require_ge(attr_range.lr_end, -1);
466466

467467
if (!(iter->sa_type == &VC_ROLE || iter->sa_type == &VC_ROLE_FG
468468
|| iter->sa_type == &VC_STYLE || iter->sa_type == &VC_GRAPHIC

0 commit comments

Comments
 (0)