Patch Detail
Show a patch.
GET /api/patches/11110/?format=api
{ "id": 11110, "url": "https://patchwork.libcamera.org/api/patches/11110/?format=api", "web_url": "https://patchwork.libcamera.org/patch/11110/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20210202221051.1740237-3-niklas.soderlund@ragnatech.se>", "date": "2021-02-02T22:10:50", "name": "[libcamera-devel,v4,2/3] cam: event_loop: Execute events in the libevent loop", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "f8bf94bf46f466ab58535a6d191911aa140f7c9a", "submitter": { "id": 5, "url": "https://patchwork.libcamera.org/api/people/5/?format=api", "name": "Niklas Söderlund", "email": "niklas.soderlund@ragnatech.se" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/11110/mbox/", "series": [ { "id": 1641, "url": "https://patchwork.libcamera.org/api/series/1641/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=1641", "date": "2021-02-02T22:10:48", "name": "cam: Fix races in event loop and long request processing times", "version": 4, "mbox": "https://patchwork.libcamera.org/series/1641/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/11110/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/11110/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 048FCBD161\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 2 Feb 2021 22:11:27 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 88B426843C;\n\tTue, 2 Feb 2021 23:11:26 +0100 (CET)", "from vsp-unauthed02.binero.net (vsp-unauthed02.binero.net\n\t[195.74.38.227])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 4B85568430\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 2 Feb 2021 23:11:25 +0100 (CET)", "from bismarck.berto.se (p4fca2458.dip0.t-ipconnect.de\n\t[79.202.36.88])\n\tby bin-vsp-out-03.atm.binero.net (Halon) with ESMTPA\n\tid 96370623-65a3-11eb-b73f-0050569116f7;\n\tTue, 02 Feb 2021 23:11:24 +0100 (CET)" ], "X-Halon-ID": "96370623-65a3-11eb-b73f-0050569116f7", "Authorized-sender": "niklas.soderlund@fsdn.se", "From": "=?utf-8?q?Niklas_S=C3=B6derlund?= <niklas.soderlund@ragnatech.se>", "To": "libcamera-devel@lists.libcamera.org", "Date": "Tue, 2 Feb 2021 23:10:50 +0100", "Message-Id": "<20210202221051.1740237-3-niklas.soderlund@ragnatech.se>", "X-Mailer": "git-send-email 2.30.0", "In-Reply-To": "<20210202221051.1740237-1-niklas.soderlund@ragnatech.se>", "References": "<20210202221051.1740237-1-niklas.soderlund@ragnatech.se>", "MIME-Version": "1.0", "Subject": "[libcamera-devel] [PATCH v4 2/3] cam: event_loop: Execute events in\n\tthe libevent loop", "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>", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "base64", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "Cam uses libevent to deal with threads and idle loop while still\nimplementing its own event queue. This creates issues when the event\nloop is terminated as it might get stuck in the idle loop if exit() is\ncalled while the thread is busy with dispatchCalls().\n\nSolve this my removing the custom event execution and instead injecting\nthe calls as events to the base event loop.\n\nReported-by: Sebastian Fricke <sebastian.fricke@posteo.net>\nSigned-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n---\n src/cam/event_loop.cpp | 43 ++++++++++++++++++++----------------------\n src/cam/event_loop.h | 6 +-----\n 2 files changed, 21 insertions(+), 28 deletions(-)", "diff": "diff --git a/src/cam/event_loop.cpp b/src/cam/event_loop.cpp\nindex 3a2b665abdc063de..e84e437f1f8ff6d7 100644\n--- a/src/cam/event_loop.cpp\n+++ b/src/cam/event_loop.cpp\n@@ -13,6 +13,13 @@\n \n EventLoop *EventLoop::instance_ = nullptr;\n \n+static void dispatchCallback([[maybe_unused]] evutil_socket_t fd,\n+\t\t\t [[maybe_unused]] short flags, void *param)\n+{\n+\tEventLoop *loop = static_cast<EventLoop *>(param);\n+\tloop->dispatchCall();\n+}\n+\n EventLoop::EventLoop()\n {\n \tassert(!instance_);\n@@ -38,25 +45,13 @@ EventLoop *EventLoop::instance()\n int EventLoop::exec()\n {\n \texitCode_ = -1;\n-\texit_.store(false, std::memory_order_release);\n-\n-\twhile (!exit_.load(std::memory_order_acquire)) {\n-\t\tdispatchCalls();\n-\t\tevent_base_loop(base_, EVLOOP_NO_EXIT_ON_EMPTY);\n-\t}\n-\n+\tevent_base_loop(base_, EVLOOP_NO_EXIT_ON_EMPTY);\n \treturn exitCode_;\n }\n \n void EventLoop::exit(int code)\n {\n \texitCode_ = code;\n-\texit_.store(true, std::memory_order_release);\n-\tinterrupt();\n-}\n-\n-void EventLoop::interrupt()\n-{\n \tevent_base_loopbreak(base_);\n }\n \n@@ -67,20 +62,22 @@ void EventLoop::callLater(const std::function<void()> &func)\n \t\tcalls_.push_back(func);\n \t}\n \n-\tinterrupt();\n+\tstruct event *event = event_new(base_, -1, 0, dispatchCallback, this);\n+\tevent_active(event, 0, 0);\n }\n \n-void EventLoop::dispatchCalls()\n+void EventLoop::dispatchCall()\n {\n-\tstd::unique_lock<std::mutex> locker(lock_);\n+\tstd::function<void()> call;\n \n-\tfor (auto iter = calls_.begin(); iter != calls_.end(); ) {\n-\t\tstd::function<void()> call = std::move(*iter);\n+\t{\n+\t\tstd::unique_lock<std::mutex> locker(lock_);\n+\t\tif (calls_.empty())\n+\t\t\treturn;\n \n-\t\titer = calls_.erase(iter);\n-\n-\t\tlocker.unlock();\n-\t\tcall();\n-\t\tlocker.lock();\n+\t\tcall = calls_.front();\n+\t\tcalls_.pop_front();\n \t}\n+\n+\tcall();\n }\ndiff --git a/src/cam/event_loop.h b/src/cam/event_loop.h\nindex d0d5b5a53c830670..5f1cd88c2f5c830e 100644\n--- a/src/cam/event_loop.h\n+++ b/src/cam/event_loop.h\n@@ -7,7 +7,6 @@\n #ifndef __CAM_EVENT_LOOP_H__\n #define __CAM_EVENT_LOOP_H__\n \n-#include <atomic>\n #include <functional>\n #include <list>\n #include <mutex>\n@@ -26,19 +25,16 @@ public:\n \tvoid exit(int code = 0);\n \n \tvoid callLater(const std::function<void()> &func);\n+\tvoid dispatchCall();\n \n private:\n \tstatic EventLoop *instance_;\n \n \tstruct event_base *base_;\n-\tstd::atomic<bool> exit_;\n \tint exitCode_;\n \n \tstd::list<std::function<void()>> calls_;\n \tstd::mutex lock_;\n-\n-\tvoid interrupt();\n-\tvoid dispatchCalls();\n };\n \n #endif /* __CAM_EVENT_LOOP_H__ */\n", "prefixes": [ "libcamera-devel", "v4", "2/3" ] }