From patchwork Sun May 23 00:04:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 12362 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 988D1C3201 for ; Sun, 23 May 2021 00:04:47 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D65BC6891E; Sun, 23 May 2021 02:04:46 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="SUydyP+B"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E648060510 for ; Sun, 23 May 2021 02:04:44 +0200 (CEST) Received: from pendragon.lan (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 4BBC72A8; Sun, 23 May 2021 02:04:44 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1621728284; bh=9a4QSCcSQhpFlqt6MUXiSr1dLRD4vaUOXuPCbw1bL2E=; h=From:To:Cc:Subject:Date:From; b=SUydyP+BJk+w5k3Vl7KugQuIqx1vzwdaOV+w0UApIj7tGjXnytZnY2u9nS4P4W3it 9p271OPPFhqFe2TPrpgk24rsyQJhX2ydyIEGk9adZ238gF8Y1lqpjpxuf7zEGEfHUp RFyj4ILCssC6TbXBx7lcY7Lo69+LJyWSGkRO5LnU= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Sun, 23 May 2021 03:04:37 +0300 Message-Id: <20210523000437.28334-1-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.28.1 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH] libcamera: log: Destroy LogCategory instances in a controlled way X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The LogCategory instances are constructed on first use as static variables in accessor functions, following the Meyers singleton pattern. As a result, their destruction order is not guaranteed. This can cause issues as the global Logger object, constructed in a similar fashion, is accessed from the LogCategory destructor and may be destroyed first. To fix this, keep the same singleton pattern, but allocate the LogCategory instances dynamically. As they get registered with the global Logger instance, we can destroy them in the Logger destructor. This only avoids destruction order issues between LogCategory and Logger, and doesn't address yet the fact that LOG() calls from destructors of global objects may access an already destroyed Logger. Signed-off-by: Laurent Pinchart Reviewed-by: Hirokazu Honda Reviewed-by: Kieran Bingham --- include/libcamera/internal/log.h | 5 ++--- src/libcamera/log.cpp | 32 +++++++++++--------------------- 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/include/libcamera/internal/log.h b/include/libcamera/internal/log.h index b66bf55bc57d..1032bdd93e7c 100644 --- a/include/libcamera/internal/log.h +++ b/include/libcamera/internal/log.h @@ -29,7 +29,6 @@ class LogCategory { public: explicit LogCategory(const char *name); - ~LogCategory(); const char *name() const { return name_; } LogSeverity severity() const { return severity_; } @@ -48,8 +47,8 @@ extern const LogCategory &_LOG_CATEGORY(name)(); #define LOG_DEFINE_CATEGORY(name) \ const LogCategory &_LOG_CATEGORY(name)() \ { \ - static LogCategory category(#name); \ - return category; \ + static LogCategory *category = new LogCategory(#name); \ + return *category; \ } class LogMessage diff --git a/src/libcamera/log.cpp b/src/libcamera/log.cpp index dd991647b9bc..74829a56916e 100644 --- a/src/libcamera/log.cpp +++ b/src/libcamera/log.cpp @@ -248,6 +248,8 @@ void LogOutput::writeStream(const std::string &str) class Logger { public: + ~Logger(); + static Logger *instance(); void write(const LogMessage &msg); @@ -267,7 +269,6 @@ private: friend LogCategory; void registerCategory(LogCategory *category); - void unregisterCategory(LogCategory *category); std::unordered_set categories_; std::list> levels_; @@ -369,6 +370,12 @@ void logSetLevel(const char *category, const char *level) Logger::instance()->logSetLevel(category, level); } +Logger::~Logger() +{ + for (LogCategory *category : categories_) + delete category; +} + /** * \brief Retrieve the logger instance * @@ -665,18 +672,6 @@ void Logger::registerCategory(LogCategory *category) } } -/** - * \brief Unregister a log category from the logger - * \param[in] category The log category - * - * If the \a category hasn't been registered with the logger this function - * performs no operation. - */ -void Logger::unregisterCategory(LogCategory *category) -{ - categories_.erase(category); -} - /** * \enum LogSeverity * Log message severity @@ -711,11 +706,6 @@ LogCategory::LogCategory(const char *name) Logger::instance()->registerCategory(this); } -LogCategory::~LogCategory() -{ - Logger::instance()->unregisterCategory(this); -} - /** * \fn LogCategory::name() * \brief Retrieve the log category name @@ -746,12 +736,12 @@ void LogCategory::setSeverity(LogSeverity severity) * The default log category is named "default" and is used by the LOG() macro * when no log category is specified. * - * \return A pointer to the default log category + * \return A reference to the default log category */ const LogCategory &LogCategory::defaultCategory() { - static const LogCategory category("default"); - return category; + static const LogCategory *category = new LogCategory("default"); + return *category; } /**