summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2019-10-28 05:31:12 +0200
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2019-10-29 16:41:54 +0200
commit3d75cc1bd209cf1de909ce5c8c9cec16789708f6 (patch)
tree5e23464cd2bbbefaaa38cbf900c809d81754ffa8
parentdf2518b2a3451ad73ebddce056b68edb98ab0f7c (diff)
libcamera: bound_method: Support connection types
Support all connection types in the BoundMethodBase::activePack() method. To support this, add a semaphore to the InvokeMessage to signal delivery. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
-rw-r--r--src/libcamera/bound_method.cpp30
-rw-r--r--src/libcamera/include/message.h5
-rw-r--r--src/libcamera/message.cpp11
-rw-r--r--src/libcamera/object.cpp8
4 files changed, 49 insertions, 5 deletions
diff --git a/src/libcamera/bound_method.cpp b/src/libcamera/bound_method.cpp
index ab6ecd94..60071736 100644
--- a/src/libcamera/bound_method.cpp
+++ b/src/libcamera/bound_method.cpp
@@ -8,6 +8,7 @@
#include <libcamera/bound_method.h>
#include "message.h"
+#include "semaphore.h"
#include "thread.h"
#include "utils.h"
@@ -49,12 +50,37 @@ namespace libcamera {
void BoundMethodBase::activatePack(void *pack)
{
- if (Thread::current() == object_->thread()) {
+ ConnectionType type = connectionType_;
+ if (type == ConnectionTypeAuto) {
+ if (Thread::current() == object_->thread())
+ type = ConnectionTypeDirect;
+ else
+ type = ConnectionTypeQueued;
+ }
+
+ switch (type) {
+ case ConnectionTypeDirect:
+ default:
invokePack(pack);
- } else {
+ break;
+
+ case ConnectionTypeQueued: {
std::unique_ptr<Message> msg =
utils::make_unique<InvokeMessage>(this, pack);
object_->postMessage(std::move(msg));
+ break;
+ }
+
+ case ConnectionTypeBlocking: {
+ Semaphore semaphore;
+
+ std::unique_ptr<Message> msg =
+ utils::make_unique<InvokeMessage>(this, pack, &semaphore);
+ object_->postMessage(std::move(msg));
+
+ semaphore.acquire();
+ break;
+ }
}
}
diff --git a/src/libcamera/include/message.h b/src/libcamera/include/message.h
index 1cfde566..311755cc 100644
--- a/src/libcamera/include/message.h
+++ b/src/libcamera/include/message.h
@@ -15,6 +15,7 @@ namespace libcamera {
class BoundMethodBase;
class Object;
+class Semaphore;
class Thread;
class Message
@@ -48,14 +49,18 @@ class InvokeMessage : public Message
{
public:
InvokeMessage(BoundMethodBase *method, void *pack,
+ Semaphore *semaphore = nullptr,
bool deleteMethod = false);
~InvokeMessage();
+ Semaphore *semaphore() const { return semaphore_; }
+
void invoke();
private:
BoundMethodBase *method_;
void *pack_;
+ Semaphore *semaphore_;
bool deleteMethod_;
};
diff --git a/src/libcamera/message.cpp b/src/libcamera/message.cpp
index efafb655..daf65322 100644
--- a/src/libcamera/message.cpp
+++ b/src/libcamera/message.cpp
@@ -119,13 +119,14 @@ Message::Type Message::registerMessageType()
* \brief Construct an InvokeMessage for method invocation on an Object
* \param[in] method The bound method
* \param[in] pack The packed method arguments
+ * \param[in] semaphore The semaphore used to signal message delivery
* \param[in] deleteMethod True to delete the \a method when the message is
* destroyed
*/
InvokeMessage::InvokeMessage(BoundMethodBase *method, void *pack,
- bool deleteMethod)
+ Semaphore *semaphore, bool deleteMethod)
: Message(Message::InvokeMessage), method_(method), pack_(pack),
- deleteMethod_(deleteMethod)
+ semaphore_(semaphore), deleteMethod_(deleteMethod)
{
}
@@ -136,6 +137,12 @@ InvokeMessage::~InvokeMessage()
}
/**
+ * \fn InvokeMessage::semaphore()
+ * \brief Retrieve the message semaphore passed to the constructor
+ * \return The message semaphore
+ */
+
+/**
* \brief Invoke the method bound to InvokeMessage::method_ with arguments
* InvokeMessage::pack_
*/
diff --git a/src/libcamera/object.cpp b/src/libcamera/object.cpp
index 98aa0af2..b0818f9a 100644
--- a/src/libcamera/object.cpp
+++ b/src/libcamera/object.cpp
@@ -13,6 +13,7 @@
#include "log.h"
#include "message.h"
+#include "semaphore.h"
#include "thread.h"
#include "utils.h"
@@ -123,7 +124,12 @@ void Object::message(Message *msg)
switch (msg->type()) {
case Message::InvokeMessage: {
InvokeMessage *iMsg = static_cast<InvokeMessage *>(msg);
+ Semaphore *semaphore = iMsg->semaphore();
iMsg->invoke();
+
+ if (semaphore)
+ semaphore->release();
+
break;
}
@@ -150,7 +156,7 @@ void Object::message(Message *msg)
void Object::invokeMethod(BoundMethodBase *method, void *args)
{
std::unique_ptr<Message> msg =
- utils::make_unique<InvokeMessage>(method, args, true);
+ utils::make_unique<InvokeMessage>(method, args, nullptr, true);
postMessage(std::move(msg));
}