summaryrefslogtreecommitdiff
path: root/src/libcamera/signal.cpp
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2019-07-10 14:47:30 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2019-07-11 11:57:37 +0300
commitcc3ae13d9edf36473fb0c4c78b9490c355ce0096 (patch)
tree5216f22dd8eda2975bc41fc6ea9d504892a62f3f /src/libcamera/signal.cpp
parent01b930964acdd9475d46044c459396f8c3cf8a79 (diff)
libcamera: signal: Support cross-thread signals
Allow signals to cross thread boundaries by posting them to the recipient through messages instead of calling the slot directly when the recipient lives in a different thread. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Diffstat (limited to 'src/libcamera/signal.cpp')
-rw-r--r--src/libcamera/signal.cpp26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/libcamera/signal.cpp b/src/libcamera/signal.cpp
index 4cb85ecb..53c18535 100644
--- a/src/libcamera/signal.cpp
+++ b/src/libcamera/signal.cpp
@@ -7,6 +7,10 @@
#include <libcamera/signal.h>
+#include "message.h"
+#include "thread.h"
+#include "utils.h"
+
/**
* \file signal.h
* \brief Signal & slot implementation
@@ -42,8 +46,30 @@ namespace libcamera {
* to the same slot. Duplicate connections between a signal and a slot are
* allowed and result in the slot being called multiple times for the same
* signal emission.
+ *
+ * When a slot belongs to an instance of the Object class, the slot is called
+ * in the context of the thread that the object is bound to. If the signal is
+ * emitted from the same thread, the slot will be called synchronously, before
+ * Signal::emit() returns. If the signal is emitted from a different thread,
+ * the slot will be called asynchronously from the object's thread's event
+ * loop, after the Signal::emit() method returns, with a copy of the signal's
+ * arguments. The emitter shall thus ensure that any pointer or reference
+ * passed through the signal will remain valid after the signal is emitted.
*/
+void SlotBase::activatePack(void *pack)
+{
+ Object *obj = static_cast<Object *>(obj_);
+
+ if (Thread::current() == obj->thread()) {
+ invokePack(pack);
+ } else {
+ std::unique_ptr<Message> msg =
+ utils::make_unique<SignalMessage>(this, pack);
+ obj->postMessage(std::move(msg));
+ }
+}
+
/**
* \fn Signal::connect(T *object, void(T::*func)(Args...))
* \brief Connect the signal to a member function slot