From patchwork Fri Nov 13 06:38:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 10417 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 01CBDBE086 for ; Fri, 13 Nov 2020 06:38:27 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 30015631C4; Fri, 13 Nov 2020 07:38:26 +0100 (CET) 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="vzyN5uxk"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id A91D7631AF for ; Fri, 13 Nov 2020 07:38:24 +0100 (CET) Received: from pendragon.lan (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 45ADFA1B for ; Fri, 13 Nov 2020 07:38:24 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1605249504; bh=14Ycuh7MxS3qAE+FZCnYtm0w6OPq3HBKUDkkJNWhlPo=; h=From:To:Subject:Date:In-Reply-To:References:From; b=vzyN5uxkfNCT/HSONJUCfvOro9GK8TRtVVEr2QFinZghLodp7Exh53YJ+pqabWMYB i4GzCV1pW467sIAgU2ZYS9QL0s0CCMHazOJWe+C0qFCEvugJeZ80YxluZNPJgHISF2 cEK9sJDoPWRNQAt7YFPIu40GlKj97lqqmFWPxPHw= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Fri, 13 Nov 2020 08:38:12 +0200 Message-Id: <20201113063815.10288-3-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201113063815.10288-1-laurent.pinchart@ideasonboard.com> References: <20201113063815.10288-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v1 2/5] cam: Use libevent to implement event loop 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" To prepare for removal of the EventDispatcher from the libcamera public API, switch to libevent to handle the event loop. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham Reviewed-by: Kieran Bingham Reviewed-by: Niklas Söderlund Reported-by: Coverity CID=305971 --- src/cam/event_loop.cpp | 34 +++++++++++++++++++++++++++------- src/cam/event_loop.h | 15 ++++++++------- src/cam/main.cpp | 16 +++++----------- src/cam/meson.build | 13 ++++++++++++- 4 files changed, 52 insertions(+), 26 deletions(-) diff --git a/src/cam/event_loop.cpp b/src/cam/event_loop.cpp index e8ab861790ed..13f2583da0a1 100644 --- a/src/cam/event_loop.cpp +++ b/src/cam/event_loop.cpp @@ -5,19 +5,34 @@ * event_loop.cpp - cam - Event loop */ -#include - #include "event_loop.h" -using namespace libcamera; +#include +#include +#include -EventLoop::EventLoop(EventDispatcher *dispatcher) - : dispatcher_(dispatcher) +EventLoop *EventLoop::instance_ = nullptr; + +EventLoop::EventLoop() { + assert(!instance_); + + evthread_use_pthreads(); + event_ = event_base_new(); + instance_ = this; } EventLoop::~EventLoop() { + instance_ = nullptr; + + event_base_free(event_); + libevent_global_shutdown(); +} + +EventLoop *EventLoop::instance() +{ + return instance_; } int EventLoop::exec() @@ -26,7 +41,7 @@ int EventLoop::exec() exit_.store(false, std::memory_order_release); while (!exit_.load(std::memory_order_acquire)) - dispatcher_->processEvents(); + event_base_loop(event_, EVLOOP_NO_EXIT_ON_EMPTY); return exitCode_; } @@ -35,5 +50,10 @@ void EventLoop::exit(int code) { exitCode_ = code; exit_.store(true, std::memory_order_release); - dispatcher_->interrupt(); + interrupt(); +} + +void EventLoop::interrupt() +{ + event_base_loopbreak(event_); } diff --git a/src/cam/event_loop.h b/src/cam/event_loop.h index 581c7cba2fc4..b1c6bd103080 100644 --- a/src/cam/event_loop.h +++ b/src/cam/event_loop.h @@ -9,26 +9,27 @@ #include -#include - -namespace libcamera { -class EventDispatcher; -} +struct event_base; class EventLoop { public: - EventLoop(libcamera::EventDispatcher *dispatcher); + EventLoop(); ~EventLoop(); + static EventLoop *instance(); + int exec(); void exit(int code = 0); private: - libcamera::EventDispatcher *dispatcher_; + static EventLoop *instance_; + struct event_base *event_; std::atomic exit_; int exitCode_; + + void interrupt(); }; #endif /* __CAM_EVENT_LOOP_H__ */ diff --git a/src/cam/main.cpp b/src/cam/main.cpp index b3a8d94f5739..e01be63a7058 100644 --- a/src/cam/main.cpp +++ b/src/cam/main.cpp @@ -52,7 +52,7 @@ private: CameraManager *cm_; std::shared_ptr camera_; std::unique_ptr config_; - EventLoop *loop_; + EventLoop loop_; bool strictFormats_; }; @@ -60,7 +60,7 @@ private: CamApp *CamApp::app_ = nullptr; CamApp::CamApp() - : cm_(nullptr), camera_(nullptr), config_(nullptr), loop_(nullptr), + : cm_(nullptr), camera_(nullptr), config_(nullptr), strictFormats_(false) { CamApp::app_ = this; @@ -134,16 +134,11 @@ int CamApp::init(int argc, char **argv) std::cout << "Monitoring new hotplug and unplug events" << std::endl; } - loop_ = new EventLoop(cm_->eventDispatcher()); - return 0; } void CamApp::cleanup() { - delete loop_; - loop_ = nullptr; - if (camera_) { camera_->release(); camera_.reset(); @@ -166,8 +161,7 @@ int CamApp::exec() void CamApp::quit() { - if (loop_) - loop_->exit(); + loop_.exit(); } int CamApp::parseOptions(int argc, char *argv[]) @@ -366,13 +360,13 @@ int CamApp::run() } if (options_.isSet(OptCapture)) { - Capture capture(camera_, config_.get(), loop_); + Capture capture(camera_, config_.get(), &loop_); return capture.run(options_); } if (options_.isSet(OptMonitor)) { std::cout << "Press Ctrl-C to interrupt" << std::endl; - ret = loop_->exec(); + ret = loop_.exec(); if (ret) std::cout << "Failed to run monitor loop" << std::endl; } diff --git a/src/cam/meson.build b/src/cam/meson.build index 89e124fbae2a..62003c58dad0 100644 --- a/src/cam/meson.build +++ b/src/cam/meson.build @@ -1,5 +1,12 @@ # SPDX-License-Identifier: CC0-1.0 +libevent = dependency('libevent_pthreads', required : false) + +if not libevent.found() + warning('libevent_pthreads not found,\'cam\' application will not be compiled') + subdir_done() +endif + cam_sources = files([ 'buffer_writer.cpp', 'capture.cpp', @@ -10,5 +17,9 @@ cam_sources = files([ ]) cam = executable('cam', cam_sources, - dependencies : [ libatomic, libcamera_dep ], + dependencies : [ + libatomic, + libcamera_dep, + libevent, + ], install : true)