Skip to content
This repository has been archived by the owner on Mar 10, 2022. It is now read-only.

Commit

Permalink
fix(screens/log): MT-related crashes when marking logs as read
Browse files Browse the repository at this point in the history
  • Loading branch information
tmplt committed Jul 10, 2019
1 parent c61c036 commit d7982c2
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ This project adheres to [Semantic Versioning](https://semver.org)
* Screens/details: "Serie" -> "Series"
* Screens/details: Correctly print empty fields.
* Screens/index: Correctly print Unicode strings. #83
* Screens/log: Possible MT-related crashes when marking log entries as seen.

## [v0.8.0] - 2019-05-26

Expand Down
27 changes: 24 additions & 3 deletions src/tui/screens/log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ namespace bookwyrm::tui::screen {

void log::maybe_update_detached(std::function<void()> &&fun)
{
assert(!entries_mutex_.try_lock());

if (detached_at_.has_value()) {
/*
* The entries_ container will after a while need to resize.
Expand All @@ -34,6 +36,8 @@ namespace bookwyrm::tui::screen {

void log::mark_read()
{
std::lock_guard<std::mutex> guard{entries_mutex_};

maybe_update_detached([&]() {
entries_.insert(entries_.end(), unread_entries_.begin(), unread_entries_.end());
unread_entries_.clear();
Expand All @@ -44,6 +48,8 @@ namespace bookwyrm::tui::screen {
/* Figure out how many entries we can fit on screen given an entry to start from. */
int log::capacity(const entry_ri &start) const
{
assert(!entries_mutex_.try_lock());

int lines = get_height();
return std::count_if(start, crend(entries_), [&](const auto e) {
lines -= std::ceil(static_cast<double>(e.second.length()) / get_width());
Expand All @@ -55,6 +61,8 @@ namespace bookwyrm::tui::screen {
{
erase();

std::lock_guard<std::mutex> guard{entries_mutex_};

entry_ri entry = std::invoke([this]() {
const auto last_entry = detached_at_.value_or(crbegin(entries_));
return last_entry - 1 + capacity(last_entry);
Expand All @@ -77,7 +85,7 @@ namespace bookwyrm::tui::screen {
* First up, split the log level from the message, and print the
* level in a fitting colour.
*/
const auto[lvl, msg] = split_at_first(entry->second, ":");
const auto [lvl, msg] = split_at_first(entry->second, ":");
print(x, y, lvl, to_colour(entry->first));
x += lvl.length();

Expand All @@ -98,13 +106,15 @@ namespace bookwyrm::tui::screen {

std::string log::footer_info() const
{
std::lock_guard<std::mutex> guard{entries_mutex_};
return fmt::format("Log entries: {}; attached to tail: {}", entries_.size(), !detached_at_.has_value());
}

std::string log::controls_legacy() const { return "[j/k d/u]Navigation [SPACE]attach/detach"; }

int log::scrollpercent() const
{
std::lock_guard<std::mutex> guard{entries_mutex_};
return ratio(std::distance(detached_at_.value_or(entries_.crbegin()), entries_.crend()), entries_.size());
}

Expand All @@ -121,7 +131,9 @@ namespace bookwyrm::tui::screen {
*/
std::replace(msg.begin(), msg.end(), '\n', ' ');

auto emplace_entry = [&](std::vector<core::log_pair> &v, core::log_level lvl, std::string msg) {
std::lock_guard<std::mutex> guard{entries_mutex_};

const auto emplace_entry = [](std::vector<core::log_pair> &v, core::log_level lvl, std::string msg) {
std::string prefix = core::loglvl_to_string(lvl);
v.emplace_back(lvl, prefix + ": " + msg);
};
Expand All @@ -140,6 +152,8 @@ namespace bookwyrm::tui::screen {

std::optional<core::log_level> log::worst_unread() const
{
std::lock_guard<std::mutex> guard{entries_mutex_};

const auto worst = std::max_element(
cbegin(unread_entries_), cend(unread_entries_), [](const auto &a, const auto &b) { return a.first < b.first; });

Expand All @@ -151,11 +165,16 @@ namespace bookwyrm::tui::screen {
return worst->first;
}

std::vector<core::log_pair> log::unread_logs() const { return std::move(unread_entries_); }
std::vector<core::log_pair> log::unread_logs() const
{
std::lock_guard<std::mutex> guard{entries_mutex_};
return std::move(unread_entries_);
}

void log::toggle_action()
{
/* Toggle log attachment. */
std::lock_guard<std::mutex> guard{entries_mutex_};

if (detached_at_.has_value())
detached_at_.reset();
Expand All @@ -165,6 +184,8 @@ namespace bookwyrm::tui::screen {

void log::move(move_direction dir)
{
std::lock_guard<std::mutex> guard{entries_mutex_};

if (!detached_at_.has_value())
return;

Expand Down

0 comments on commit d7982c2

Please sign in to comment.