From patchwork Thu Jan 30 11:50:36 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= X-Patchwork-Id: 22674 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 B549ABDB1C for ; Thu, 30 Jan 2025 11:51:35 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2B4446857F; Thu, 30 Jan 2025 12:51:35 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=protonmail.com header.i=@protonmail.com header.b="GVWVCYaN"; dkim-atps=neutral Received: from mail-10631.protonmail.ch (mail-10631.protonmail.ch [79.135.106.31]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EE3476857E for ; Thu, 30 Jan 2025 12:51:31 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=protonmail3; t=1738237891; x=1738497091; bh=NUhrDH+R6HSzEFO8Hof78/dy7krBWAL7vNTi4zrPXrY=; h=Date:To:From:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector:List-Unsubscribe:List-Unsubscribe-Post; b=GVWVCYaN5/iPLofg/GD/TfzViRuAgtpgZfts7Vg+5W0vDg1GwkZ20lHg55hRxa/68 DqkkvixdkJNtnTIuCZFdXfAtAzcGOp26sX++NxlG5tPMw1PTxnAaZMRQe+BF1+s6Cp C4AGE47TO4qP098cFBYqogV4KX3bNSUYFClulo/g33+ZS+QVJdaZjSIIdZs2hHk/Dq 2Mn/qtc9cGMSabLjF7dINOnT0/rLJS8hQpLUbTAY9XsxolBe9t01ClcJlpEYpjAZ9B lKRx6DjAjiqZZ7kxoBR/MhGNkhR33r76ppYcljrcr1zGWAQbQztKkroXl/9chOM+mU OwoXu0vkxbHTA== Date: Thu, 30 Jan 2025 11:50:36 +0000 To: libcamera-devel@lists.libcamera.org From: =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= Subject: [RFC PATCH v3 07/21] apps: common: event_loop: Make it possible to exit with exception Message-ID: <20250130115001.1129305-8-pobrn@protonmail.com> In-Reply-To: <20250130115001.1129305-1-pobrn@protonmail.com> References: <20250130115001.1129305-1-pobrn@protonmail.com> Feedback-ID: 20568564:user:proton X-Pm-Message-ID: 1d14dc4b50c39baa5b13ef346ff4914946cd24f8 MIME-Version: 1.0 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" Instead of taking a single integer in `EventLoop:exit()`, change it so that an `std::exception_ptr` can also be passed. And in `EventLoop::exec()` rethrow the stored exception (if any). Furthermore, catch exceptions from deferred calls, and stop the event loop with the caught exception. Signed-off-by: Barnabás Pőcze --- src/apps/common/event_loop.cpp | 35 +++++++++++++++++++++++++++++----- src/apps/common/event_loop.h | 6 ++++-- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/apps/common/event_loop.cpp b/src/apps/common/event_loop.cpp index 0d7a4a024..13c2d6057 100644 --- a/src/apps/common/event_loop.cpp +++ b/src/apps/common/event_loop.cpp @@ -12,6 +12,7 @@ #include #include #include +#include EventLoop *EventLoop::instance_ = nullptr; @@ -38,7 +39,14 @@ EventLoop::EventLoop() self->calls_.pop_front(); } - call(); + try { + call(); + } + catch (...) { + ::event_active(self->callsTrigger_, 0, 0); + self->exit(std::current_exception()); + break; + } } }, this); assert(callsTrigger_); @@ -63,14 +71,31 @@ EventLoop *EventLoop::instance() int EventLoop::exec() { - exitCode_ = -1; + { + std::lock_guard locker(lock_); + result_ = 0; + } + event_base_loop(base_, EVLOOP_NO_EXIT_ON_EMPTY); - return exitCode_; + + auto result = [&] { + std::lock_guard locker(lock_); + return std::exchange(result_, 0); + }(); + + if (auto *exc = std::get_if(&result)) + std::rethrow_exception(std::move(*exc)); + + return std::get(result); } -void EventLoop::exit(int code) +void EventLoop::exit(std::variant result) { - exitCode_ = code; + { + std::lock_guard locker(lock_); + result_ = std::move(result); + } + event_base_loopbreak(base_); } diff --git a/src/apps/common/event_loop.h b/src/apps/common/event_loop.h index 6d7d0497a..380c3483a 100644 --- a/src/apps/common/event_loop.h +++ b/src/apps/common/event_loop.h @@ -9,11 +9,13 @@ #include #include +#include #include #include #include #include #include +#include #include @@ -35,7 +37,7 @@ public: static EventLoop *instance(); int exec(); - void exit(int code = 0); + void exit(std::variant result = 0); void callLater(std::function &&func, std::optional cookie = {}); void cancelLater(std::optional cookie = {}); @@ -63,7 +65,7 @@ private: static EventLoop *instance_; struct event_base *base_; - int exitCode_; + std::variant result_ = 0; std::deque, std::optional>> calls_; ::event *callsTrigger_ = nullptr;