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>
* 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 *
* *
* Copyright 2020 Markus Gans *
* Copyright 2020-2021 Markus Gans *
* *
* FINAL CUT is free software; you can redistribute it and/or modify *
* 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;
sync();
std::lock_guard<std::mutex> lock_guard(mut);
std::lock_guard<std::mutex> lock_guard(current_log_mutex);
switch ( l )
{
@ -74,7 +74,6 @@ int FLog::sync()
{
if ( ! str().empty() )
{
std::lock_guard<std::mutex> lock_guard(mut);
current_log (str());
str("");
}

View File

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

View File

@ -174,6 +174,13 @@ FWidget* FWidget::getParentWidget() const
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)
{
@ -982,10 +989,10 @@ void FWidget::show()
{
for (auto&& child : getChildren())
{
auto widget = static_cast<FWidget*>(child);
auto child_widget = static_cast<FWidget*>(child);
if ( child->isWidget() && ! widget->flags.hidden )
widget->show();
if ( child->isWidget() && ! child_widget->flags.hidden )
child_widget->show();
}
}

View File

@ -3,7 +3,7 @@
* *
* 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 *
* it under the terms of the GNU Lesser General Public License as *
@ -102,14 +102,14 @@ class FLog : public std::stringbuf
LogLevel& setLevel();
const LineEnding& getEnding();
LineEnding& setEnding();
std::mutex& getMutex();
private:
// Data member
LogLevel level{LogLevel::Info};
LineEnding end_of_line{LineEnding::CRLF};
std::mutex mut{};
FLogPrint current_log{std::bind(&FLog::info, this, std::placeholders::_1)};
std::mutex current_log_mutex{};
std::mutex stream_mutex{};
std::ostream stream{this};
// Friend Non-member operator functions
@ -121,7 +121,7 @@ class FLog : public std::stringbuf
template <typename T>
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;
return *this;
}
@ -129,7 +129,7 @@ inline FLog& FLog::operator << (const T& s)
//----------------------------------------------------------------------
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);
return *this;
}
@ -153,7 +153,6 @@ inline FLog::LogLevel& FLog::setLevel()
//----------------------------------------------------------------------
inline const FLog::LineEnding& FLog::getEnding()
{
std::lock_guard<std::mutex> lock_guard(mut);
return end_of_line;
}
@ -163,10 +162,6 @@ inline FLog::LineEnding& FLog::setEnding()
return end_of_line;
}
//----------------------------------------------------------------------
inline std::mutex& FLog::getMutex()
{ return mut; }
} // namespace finalcut
#endif // FLOG_H

View File

@ -3,7 +3,7 @@
* *
* 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 *
* it under the terms of the GNU Lesser General Public License as *
@ -92,6 +92,8 @@ class FLogger : public FLog
// Data member
bool timestamp{false};
std::mutex print_mutex{};
std::mutex output_mutex{};
std::ostream output{std::cerr.rdbuf()};
};
@ -103,7 +105,7 @@ inline FString FLogger::getClassName() const
//----------------------------------------------------------------------
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;
printLogLine (msg);
}
@ -111,7 +113,7 @@ inline void FLogger::info (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;
printLogLine (msg);
}
@ -119,7 +121,7 @@ inline void FLogger::warn (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;
printLogLine (msg);
}
@ -127,7 +129,7 @@ inline void FLogger::error (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;
printLogLine (msg);
}
@ -135,35 +137,35 @@ inline void FLogger::debug (const std::string& msg)
//----------------------------------------------------------------------
inline void FLogger::flush()
{
std::lock_guard<std::mutex> lock_guard(getMutex());
std::lock_guard<std::mutex> lock_guard(output_mutex);
output.flush();
}
//----------------------------------------------------------------------
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());
}
//----------------------------------------------------------------------
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;
}
//----------------------------------------------------------------------
inline void FLogger::enableTimestamp()
{
std::lock_guard<std::mutex> lock_guard(getMutex());
std::lock_guard<std::mutex> lock_guard(print_mutex);
timestamp = true;
}
//----------------------------------------------------------------------
inline void FLogger::disableTimestamp()
{
std::lock_guard<std::mutex> lock_guard(getMutex());
std::lock_guard<std::mutex> lock_guard(print_mutex);
timestamp = false;
}

View File

@ -561,13 +561,6 @@ inline FMenuBar* FWidget::getMenuBar()
inline FStatusBar* FWidget::getStatusBar()
{ 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
{ return accelerator_list; }