{"id":12362,"url":"https://patchwork.libcamera.org/api/1.1/patches/12362/?format=json","web_url":"https://patchwork.libcamera.org/patch/12362/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/1.1/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20210523000437.28334-1-laurent.pinchart@ideasonboard.com>","date":"2021-05-23T00:04:37","name":"[libcamera-devel] libcamera: log: Destroy LogCategory instances in a controlled way","commit_ref":null,"pull_url":null,"state":"accepted","archived":false,"hash":"0847c6b99fc99dd7a891e686d3a71d64f04e96d2","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/1.1/people/2/?format=json","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/12362/mbox/","series":[{"id":2048,"url":"https://patchwork.libcamera.org/api/1.1/series/2048/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=2048","date":"2021-05-23T00:04:37","name":"[libcamera-devel] libcamera: log: Destroy LogCategory instances in a controlled way","version":1,"mbox":"https://patchwork.libcamera.org/series/2048/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/12362/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/12362/checks/","tags":{},"headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 988D1C3201\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSun, 23 May 2021 00:04:47 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id D65BC6891E;\n\tSun, 23 May 2021 02:04:46 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id E648060510\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun, 23 May 2021 02:04:44 +0200 (CEST)","from pendragon.lan (62-78-145-57.bb.dnainternet.fi [62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 4BBC72A8;\n\tSun, 23 May 2021 02:04:44 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"SUydyP+B\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1621728284;\n\tbh=9a4QSCcSQhpFlqt6MUXiSr1dLRD4vaUOXuPCbw1bL2E=;\n\th=From:To:Cc:Subject:Date:From;\n\tb=SUydyP+BJk+w5k3Vl7KugQuIqx1vzwdaOV+w0UApIj7tGjXnytZnY2u9nS4P4W3it\n\t9p271OPPFhqFe2TPrpgk24rsyQJhX2ydyIEGk9adZ238gF8Y1lqpjpxuf7zEGEfHUp\n\tRFyj4ILCssC6TbXBx7lcY7Lo69+LJyWSGkRO5LnU=","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","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","Content-Transfer-Encoding":"8bit","Subject":"[libcamera-devel] [PATCH] libcamera: log: Destroy LogCategory\n\tinstances in a controlled way","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"},"content":"The LogCategory instances are constructed on first use as static\nvariables in accessor functions, following the Meyers singleton pattern.\nAs a result, their destruction order is not guaranteed. This can cause\nissues as the global Logger object, constructed in a similar fashion, is\naccessed from the LogCategory destructor and may be destroyed first.\n\nTo fix this, keep the same singleton pattern, but allocate the\nLogCategory instances dynamically. As they get registered with the\nglobal Logger instance, we can destroy them in the Logger destructor.\n\nThis only avoids destruction order issues between LogCategory and\nLogger, and doesn't address yet the fact that LOG() calls from\ndestructors of global objects may access an already destroyed Logger.\n\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\n include/libcamera/internal/log.h |  5 ++---\n src/libcamera/log.cpp            | 32 +++++++++++---------------------\n 2 files changed, 13 insertions(+), 24 deletions(-)","diff":"diff --git a/include/libcamera/internal/log.h b/include/libcamera/internal/log.h\nindex b66bf55bc57d..1032bdd93e7c 100644\n--- a/include/libcamera/internal/log.h\n+++ b/include/libcamera/internal/log.h\n@@ -29,7 +29,6 @@ class LogCategory\n {\n public:\n \texplicit LogCategory(const char *name);\n-\t~LogCategory();\n \n \tconst char *name() const { return name_; }\n \tLogSeverity severity() const { return severity_; }\n@@ -48,8 +47,8 @@ extern const LogCategory &_LOG_CATEGORY(name)();\n #define LOG_DEFINE_CATEGORY(name)\t\t\t\t\t\\\n const LogCategory &_LOG_CATEGORY(name)()\t\t\t\t\\\n {\t\t\t\t\t\t\t\t\t\\\n-\tstatic LogCategory category(#name);\t\t\t\t\\\n-\treturn category;\t\t\t\t\t\t\\\n+\tstatic LogCategory *category = new LogCategory(#name);\t\t\\\n+\treturn *category;\t\t\t\t\t\t\\\n }\n \n class LogMessage\ndiff --git a/src/libcamera/log.cpp b/src/libcamera/log.cpp\nindex dd991647b9bc..74829a56916e 100644\n--- a/src/libcamera/log.cpp\n+++ b/src/libcamera/log.cpp\n@@ -248,6 +248,8 @@ void LogOutput::writeStream(const std::string &str)\n class Logger\n {\n public:\n+\t~Logger();\n+\n \tstatic Logger *instance();\n \n \tvoid write(const LogMessage &msg);\n@@ -267,7 +269,6 @@ private:\n \n \tfriend LogCategory;\n \tvoid registerCategory(LogCategory *category);\n-\tvoid unregisterCategory(LogCategory *category);\n \n \tstd::unordered_set<LogCategory *> categories_;\n \tstd::list<std::pair<std::string, LogSeverity>> levels_;\n@@ -369,6 +370,12 @@ void logSetLevel(const char *category, const char *level)\n \tLogger::instance()->logSetLevel(category, level);\n }\n \n+Logger::~Logger()\n+{\n+\tfor (LogCategory *category : categories_)\n+\t\tdelete category;\n+}\n+\n /**\n  * \\brief Retrieve the logger instance\n  *\n@@ -665,18 +672,6 @@ void Logger::registerCategory(LogCategory *category)\n \t}\n }\n \n-/**\n- * \\brief Unregister a log category from the logger\n- * \\param[in] category The log category\n- *\n- * If the \\a category hasn't been registered with the logger this function\n- * performs no operation.\n- */\n-void Logger::unregisterCategory(LogCategory *category)\n-{\n-\tcategories_.erase(category);\n-}\n-\n /**\n  * \\enum LogSeverity\n  * Log message severity\n@@ -711,11 +706,6 @@ LogCategory::LogCategory(const char *name)\n \tLogger::instance()->registerCategory(this);\n }\n \n-LogCategory::~LogCategory()\n-{\n-\tLogger::instance()->unregisterCategory(this);\n-}\n-\n /**\n  * \\fn LogCategory::name()\n  * \\brief Retrieve the log category name\n@@ -746,12 +736,12 @@ void LogCategory::setSeverity(LogSeverity severity)\n  * The default log category is named \"default\" and is used by the LOG() macro\n  * when no log category is specified.\n  *\n- * \\return A pointer to the default log category\n+ * \\return A reference to the default log category\n  */\n const LogCategory &LogCategory::defaultCategory()\n {\n-\tstatic const LogCategory category(\"default\");\n-\treturn category;\n+\tstatic const LogCategory *category = new LogCategory(\"default\");\n+\treturn *category;\n }\n \n /**\n","prefixes":["libcamera-devel"]}