[libcamera-devel] cam: Add event loop

Message ID 20190125145417.5384-1-laurent.pinchart@ideasonboard.com
State Accepted
Commit 71ef5532d9777e9511bc982cab33e3d2d95cf4be
Headers show
Series
  • [libcamera-devel] cam: Add event loop
Related show

Commit Message

Laurent Pinchart Jan. 25, 2019, 2:54 p.m. UTC
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@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

Comments

Niklas Söderlund Jan. 25, 2019, 3:19 p.m. UTC | #1
Hi Laurent,

Thanks for your work.

On 2019-01-25 16:54:17 +0200, Laurent Pinchart wrote:
> 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@ideasonboard.com>

Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>

> ---
>  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
> 
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel@lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel

Patch

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',
 ])