Fixed mutex deadlock in FLogger

This commit is contained in:
Markus Gans 2021-04-24 17:00:28 +02:00
parent 38df8e2db2
commit 8d54e1c11f
7 changed files with 33 additions and 37 deletions

View File

@ -1,3 +1,6 @@
2021-04-24 Markus Gans <guru.mail@muenster.de>
* Fixed mutex deadlock in FLogger
2021-04-21 Markus Gans <guru.mail@muenster.de> 2021-04-21 Markus Gans <guru.mail@muenster.de>
* Fixes the detection of the terminal size after a SIGWINCH signal * Fixes the detection of the terminal size after a SIGWINCH signal

View File

@ -3,7 +3,7 @@
* * * *
* This file is part of the FINAL CUT widget toolkit * * This file is part of the FINAL CUT widget toolkit *
* * * *
* Copyright 2020 Markus Gans * * Copyright 2020-2021 Markus Gans *
* * * *
* FINAL CUT is free software; you can redistribute it and/or modify * * FINAL CUT is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as * * it under the terms of the GNU Lesser General Public License as *
@ -43,7 +43,7 @@ FLog& FLog::operator << (LogLevel l)
{ {
using std::placeholders::_1; using std::placeholders::_1;
sync(); sync();
std::lock_guard<std::mutex> lock_guard(mut); std::lock_guard<std::mutex> lock_guard(current_log_mutex);
switch ( l ) switch ( l )
{ {
@ -74,7 +74,6 @@ int FLog::sync()
{ {
if ( ! str().empty() ) if ( ! str().empty() )
{ {
std::lock_guard<std::mutex> lock_guard(mut);
current_log (str()); current_log (str());
str(""); str("");
} }

View File

@ -69,8 +69,6 @@ std::string FLogger::getTimeString() const
//---------------------------------------------------------------------- //----------------------------------------------------------------------
std::string FLogger::getEOL() std::string FLogger::getEOL()
{ {
std::lock_guard<std::mutex> lock_guard(getMutex());
if ( getEnding() == LineEnding::LF ) if ( getEnding() == LineEnding::LF )
return "\n"; return "\n";
else if ( getEnding() == LineEnding::CR ) else if ( getEnding() == LineEnding::CR )
@ -86,8 +84,6 @@ void FLogger::printLogLine (const std::string& msg)
{ {
const std::string& log_level = [this] () const std::string& log_level = [this] ()
{ {
std::lock_guard<std::mutex> lock_guard(getMutex());
switch ( getLevel() ) switch ( getLevel() )
{ {
case LogLevel::Info: case LogLevel::Info:
@ -118,6 +114,7 @@ void FLogger::printLogLine (const std::string& msg)
const std::string& eol = getEOL(); const std::string& eol = getEOL();
const std::string replace_str = eol + prefix; const std::string replace_str = eol + prefix;
newlineReplace (message, replace_str); newlineReplace (message, replace_str);
std::lock_guard<std::mutex> lock_guard(output_mutex);
output << prefix << message << eol; output << prefix << message << eol;
} }

View File

@ -174,6 +174,13 @@ FWidget* FWidget::getParentWidget() const
return nullptr; return nullptr;
} }
//----------------------------------------------------------------------
auto FWidget::getColorTheme() -> std::shared_ptr<FWidgetColors>&
{
static const auto& color_theme = make_unique<std::shared_ptr<FWidgetColors>>();
return *color_theme;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
FWidget* FWidget::getFirstFocusableWidget (FObjectList list) FWidget* FWidget::getFirstFocusableWidget (FObjectList list)
{ {
@ -982,10 +989,10 @@ void FWidget::show()
{ {
for (auto&& child : getChildren()) for (auto&& child : getChildren())
{ {
auto widget = static_cast<FWidget*>(child); auto child_widget = static_cast<FWidget*>(child);
if ( child->isWidget() && ! widget->flags.hidden ) if ( child->isWidget() && ! child_widget->flags.hidden )
widget->show(); child_widget->show();
} }
} }

View File

@ -3,7 +3,7 @@
* * * *
* This file is part of the FINAL CUT widget toolkit * * This file is part of the FINAL CUT widget toolkit *
* * * *
* Copyright 2020 Markus Gans * * Copyright 2020-2021 Markus Gans *
* * * *
* FINAL CUT is free software; you can redistribute it and/or modify * * FINAL CUT is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as * * it under the terms of the GNU Lesser General Public License as *
@ -102,14 +102,14 @@ class FLog : public std::stringbuf
LogLevel& setLevel(); LogLevel& setLevel();
const LineEnding& getEnding(); const LineEnding& getEnding();
LineEnding& setEnding(); LineEnding& setEnding();
std::mutex& getMutex();
private: private:
// Data member // Data member
LogLevel level{LogLevel::Info}; LogLevel level{LogLevel::Info};
LineEnding end_of_line{LineEnding::CRLF}; LineEnding end_of_line{LineEnding::CRLF};
std::mutex mut{};
FLogPrint current_log{std::bind(&FLog::info, this, std::placeholders::_1)}; FLogPrint current_log{std::bind(&FLog::info, this, std::placeholders::_1)};
std::mutex current_log_mutex{};
std::mutex stream_mutex{};
std::ostream stream{this}; std::ostream stream{this};
// Friend Non-member operator functions // Friend Non-member operator functions
@ -121,7 +121,7 @@ class FLog : public std::stringbuf
template <typename T> template <typename T>
inline FLog& FLog::operator << (const T& s) inline FLog& FLog::operator << (const T& s)
{ {
std::lock_guard<std::mutex> lock_guard(mut); std::lock_guard<std::mutex> lock_guard(stream_mutex);
stream << s; stream << s;
return *this; return *this;
} }
@ -129,7 +129,7 @@ inline FLog& FLog::operator << (const T& s)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline FLog& FLog::operator << (IOManip pf) inline FLog& FLog::operator << (IOManip pf)
{ {
std::lock_guard<std::mutex> lock_guard(mut); std::lock_guard<std::mutex> lock_guard(stream_mutex);
pf(stream); pf(stream);
return *this; return *this;
} }
@ -153,7 +153,6 @@ inline FLog::LogLevel& FLog::setLevel()
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline const FLog::LineEnding& FLog::getEnding() inline const FLog::LineEnding& FLog::getEnding()
{ {
std::lock_guard<std::mutex> lock_guard(mut);
return end_of_line; return end_of_line;
} }
@ -163,10 +162,6 @@ inline FLog::LineEnding& FLog::setEnding()
return end_of_line; return end_of_line;
} }
//----------------------------------------------------------------------
inline std::mutex& FLog::getMutex()
{ return mut; }
} // namespace finalcut } // namespace finalcut
#endif // FLOG_H #endif // FLOG_H

View File

@ -3,7 +3,7 @@
* * * *
* This file is part of the FINAL CUT widget toolkit * * This file is part of the FINAL CUT widget toolkit *
* * * *
* Copyright 2020 Markus Gans * * Copyright 2020-2021 Markus Gans *
* * * *
* FINAL CUT is free software; you can redistribute it and/or modify * * FINAL CUT is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as * * it under the terms of the GNU Lesser General Public License as *
@ -92,6 +92,8 @@ class FLogger : public FLog
// Data member // Data member
bool timestamp{false}; bool timestamp{false};
std::mutex print_mutex{};
std::mutex output_mutex{};
std::ostream output{std::cerr.rdbuf()}; std::ostream output{std::cerr.rdbuf()};
}; };
@ -103,7 +105,7 @@ inline FString FLogger::getClassName() const
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FLogger::info (const std::string& msg) inline void FLogger::info (const std::string& msg)
{ {
std::lock_guard<std::mutex> lock_guard(getMutex()); std::lock_guard<std::mutex> lock_guard(print_mutex);
setLevel() = LogLevel::Info; setLevel() = LogLevel::Info;
printLogLine (msg); printLogLine (msg);
} }
@ -111,7 +113,7 @@ inline void FLogger::info (const std::string& msg)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FLogger::warn (const std::string& msg) inline void FLogger::warn (const std::string& msg)
{ {
std::lock_guard<std::mutex> lock_guard(getMutex()); std::lock_guard<std::mutex> lock_guard(print_mutex);
setLevel() = LogLevel::Warn; setLevel() = LogLevel::Warn;
printLogLine (msg); printLogLine (msg);
} }
@ -119,7 +121,7 @@ inline void FLogger::warn (const std::string& msg)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FLogger::error (const std::string& msg) inline void FLogger::error (const std::string& msg)
{ {
std::lock_guard<std::mutex> lock_guard(getMutex()); std::lock_guard<std::mutex> lock_guard(print_mutex);
setLevel() = LogLevel::Error; setLevel() = LogLevel::Error;
printLogLine (msg); printLogLine (msg);
} }
@ -127,7 +129,7 @@ inline void FLogger::error (const std::string& msg)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FLogger::debug (const std::string& msg) inline void FLogger::debug (const std::string& msg)
{ {
std::lock_guard<std::mutex> lock_guard(getMutex()); std::lock_guard<std::mutex> lock_guard(print_mutex);
setLevel() = LogLevel::Debug; setLevel() = LogLevel::Debug;
printLogLine (msg); printLogLine (msg);
} }
@ -135,35 +137,35 @@ inline void FLogger::debug (const std::string& msg)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FLogger::flush() inline void FLogger::flush()
{ {
std::lock_guard<std::mutex> lock_guard(getMutex()); std::lock_guard<std::mutex> lock_guard(output_mutex);
output.flush(); output.flush();
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FLogger::setOutputStream (const std::ostream& os) inline void FLogger::setOutputStream (const std::ostream& os)
{ {
std::lock_guard<std::mutex> lock_guard(getMutex()); std::lock_guard<std::mutex> lock_guard(output_mutex);
output.rdbuf(os.rdbuf()); output.rdbuf(os.rdbuf());
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FLogger::setLineEnding (LineEnding eol) inline void FLogger::setLineEnding (LineEnding eol)
{ {
std::lock_guard<std::mutex> lock_guard(getMutex()); std::lock_guard<std::mutex> lock_guard(print_mutex);
setEnding() = eol; setEnding() = eol;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FLogger::enableTimestamp() inline void FLogger::enableTimestamp()
{ {
std::lock_guard<std::mutex> lock_guard(getMutex()); std::lock_guard<std::mutex> lock_guard(print_mutex);
timestamp = true; timestamp = true;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline void FLogger::disableTimestamp() inline void FLogger::disableTimestamp()
{ {
std::lock_guard<std::mutex> lock_guard(getMutex()); std::lock_guard<std::mutex> lock_guard(print_mutex);
timestamp = false; timestamp = false;
} }

View File

@ -561,13 +561,6 @@ inline FMenuBar* FWidget::getMenuBar()
inline FStatusBar* FWidget::getStatusBar() inline FStatusBar* FWidget::getStatusBar()
{ return statusbar; } { return statusbar; }
//----------------------------------------------------------------------
inline auto FWidget::getColorTheme() -> std::shared_ptr<FWidgetColors>&
{
static const auto& color_theme = make_unique<std::shared_ptr<FWidgetColors>>();
return *color_theme;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
inline const FWidget::FAcceleratorList& FWidget::getAcceleratorList() const inline const FWidget::FAcceleratorList& FWidget::getAcceleratorList() const
{ return accelerator_list; } { return accelerator_list; }