diff options
-rw-r--r-- | src/libcamera/bound_method.cpp | 22 | ||||
-rw-r--r-- | test/object-invoke.cpp | 20 |
2 files changed, 34 insertions, 8 deletions
diff --git a/src/libcamera/bound_method.cpp b/src/libcamera/bound_method.cpp index e18c2eb4..9aa59dc3 100644 --- a/src/libcamera/bound_method.cpp +++ b/src/libcamera/bound_method.cpp @@ -35,16 +35,19 @@ namespace libcamera { * thread. * * \var ConnectionType::ConnectionTypeQueued - * \brief The receiver is invoked asynchronously in its thread when control - * returns to the thread's event loop. The sender proceeds without waiting for - * the invocation to complete. + * \brief The receiver is invoked asynchronously + * + * Invoke the receiver asynchronously in its thread when control returns to the + * thread's event loop. The sender proceeds without waiting for the invocation + * to complete. * * \var ConnectionType::ConnectionTypeBlocking - * \brief The receiver is invoked asynchronously in its thread when control - * returns to the thread's event loop. The sender blocks until the receiver - * signals the completion of the invocation. This connection type shall not be - * used when the sender and receiver live in the same thread, otherwise - * deadlock will occur. + * \brief The receiver is invoked synchronously + * + * If the sender and the receiver live in the same thread, this is equivalent to + * ConnectionTypeDirect. Otherwise, the receiver is invoked asynchronously in + * its thread when control returns to the thread's event loop. The sender + * blocks until the receiver signals the completion of the invocation. */ /** @@ -71,6 +74,9 @@ bool BoundMethodBase::activatePack(std::shared_ptr<BoundMethodPackBase> pack, type = ConnectionTypeDirect; else type = ConnectionTypeQueued; + } else if (type == ConnectionTypeBlocking) { + if (Thread::current() == object_->thread()) + type = ConnectionTypeDirect; } switch (type) { diff --git a/test/object-invoke.cpp b/test/object-invoke.cpp index 8e2055ca..fa162c83 100644 --- a/test/object-invoke.cpp +++ b/test/object-invoke.cpp @@ -101,6 +101,26 @@ protected: } /* + * Test that blocking invocation is delivered directly when the + * caller and callee live in the same thread. + */ + object_.reset(); + + object_.invokeMethod(&InvokedObject::method, + ConnectionTypeBlocking, 42); + + switch (object_.status()) { + case InvokedObject::NoCall: + cout << "Method not invoked for main thread (blocking)" << endl; + return TestFail; + case InvokedObject::InvalidThread: + cout << "Method invoked in incorrect thread for main thread (blocking)" << endl; + return TestFail; + default: + break; + } + + /* * Move the object to a thread and verify that auto method * invocation is delivered in the correct thread. */ |