[libcamera-devel] [PATCH] cam: Add event loop

Laurent Pinchart laurent.pinchart at ideasonboard.com
Fri Jan 25 15:54:17 CET 2019


Add a simple event loop to the cam application and use it in the main()
function, with an example of how to handle SIGINT to gracefully stop the
loop.

Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
 src/cam/event_loop.cpp | 39 +++++++++++++++++++++++++++++++++++++++
 src/cam/event_loop.h   | 34 ++++++++++++++++++++++++++++++++++
 src/cam/main.cpp       | 22 +++++++++++++++++++++-
 src/cam/meson.build    |  1 +
 4 files changed, 95 insertions(+), 1 deletion(-)
 create mode 100644 src/cam/event_loop.cpp
 create mode 100644 src/cam/event_loop.h

diff --git a/src/cam/event_loop.cpp b/src/cam/event_loop.cpp
new file mode 100644
index 000000000000..e8ab861790ed
--- /dev/null
+++ b/src/cam/event_loop.cpp
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2019, Google Inc.
+ *
+ * event_loop.cpp - cam - Event loop
+ */
+
+#include <libcamera/event_dispatcher.h>
+
+#include "event_loop.h"
+
+using namespace libcamera;
+
+EventLoop::EventLoop(EventDispatcher *dispatcher)
+	: dispatcher_(dispatcher)
+{
+}
+
+EventLoop::~EventLoop()
+{
+}
+
+int EventLoop::exec()
+{
+	exitCode_ = -1;
+	exit_.store(false, std::memory_order_release);
+
+	while (!exit_.load(std::memory_order_acquire))
+		dispatcher_->processEvents();
+
+	return exitCode_;
+}
+
+void EventLoop::exit(int code)
+{
+	exitCode_ = code;
+	exit_.store(true, std::memory_order_release);
+	dispatcher_->interrupt();
+}
diff --git a/src/cam/event_loop.h b/src/cam/event_loop.h
new file mode 100644
index 000000000000..aaca5838f979
--- /dev/null
+++ b/src/cam/event_loop.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2019, Google Inc.
+ *
+ * event_loop.h - cam - Event loop
+ */
+#ifndef __CAM_EVENT_LOOP_H__
+#define __CAM_EVENT_LOOP_H__
+
+#include <atomic>
+
+#include <libcamera/event_notifier.h>
+
+namespace libcamera {
+class EventDispatcher;
+};
+
+class EventLoop
+{
+public:
+	EventLoop(libcamera::EventDispatcher *dispatcher);
+	~EventLoop();
+
+	int exec();
+	void exit(int code = 0);
+
+private:
+	libcamera::EventDispatcher *dispatcher_;
+
+	std::atomic<bool> exit_;
+	int exitCode_;
+};
+
+#endif /* __CAM_EVENT_LOOP_H__ */
diff --git a/src/cam/main.cpp b/src/cam/main.cpp
index 0d37039f5349..cb98d302dcf3 100644
--- a/src/cam/main.cpp
+++ b/src/cam/main.cpp
@@ -7,10 +7,12 @@
 
 #include <iostream>
 #include <map>
+#include <signal.h>
 #include <string.h>
 
 #include <libcamera/libcamera.h>
 
+#include "event_loop.h"
 #include "options.h"
 
 using namespace libcamera;
@@ -23,6 +25,14 @@ enum {
 	OptList = 'l',
 };
 
+EventLoop *loop;
+
+void signalHandler(int signal)
+{
+	std::cout << "Exiting" << std::endl;
+	loop->exit();
+}
+
 static int parseOptions(int argc, char *argv[])
 {
 	OptionsParser parser;
@@ -79,7 +89,17 @@ int main(int argc, char **argv)
 		}
 	}
 
+	loop = new EventLoop(cm->eventDispatcher());
+
+	struct sigaction sa = {};
+	sa.sa_handler = &signalHandler;
+	sigaction(SIGINT, &sa, nullptr);
+
+	ret = loop->exec();
+
+	delete loop;
+
 	cm->stop();
 
-	return 0;
+	return ret;
 }
diff --git a/src/cam/meson.build b/src/cam/meson.build
index e45e5391f679..cc647523955f 100644
--- a/src/cam/meson.build
+++ b/src/cam/meson.build
@@ -1,4 +1,5 @@
 cam_sources = files([
+    'event_loop.cpp',
     'main.cpp',
     'options.cpp',
 ])
-- 
Regards,

Laurent Pinchart



More information about the libcamera-devel mailing list