libcamera: object: Add connection type parameter to invokeMethod()

Allow specifying a different connection type than ConnectionTypeQueued
for Object::invokeMethod().

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
This commit is contained in:
Jacopo Mondi 2019-10-27 02:45:17 +02:00 committed by Laurent Pinchart
parent 06008b9156
commit fb1a5c0416
6 changed files with 21 additions and 16 deletions

View file

@ -30,12 +30,11 @@ public:
void postMessage(std::unique_ptr<Message> msg);
template<typename T, typename... Args, typename std::enable_if<std::is_base_of<Object, T>::value>::type * = nullptr>
void invokeMethod(void (T::*func)(Args...), Args... args)
void invokeMethod(void (T::*func)(Args...), ConnectionType type, Args... args)
{
T *obj = static_cast<T *>(this);
BoundMethodBase *method =
new BoundMemberMethod<T, Args...>(obj, this, func,
ConnectionTypeQueued);
new BoundMemberMethod<T, Args...>(obj, this, func, type);
void *pack = new typename BoundMemberMethod<T, Args...>::PackType{ args... };
method->activatePack(pack, true);

View file

@ -187,6 +187,7 @@ int CameraProxy::processCaptureRequest(camera3_capture_request_t *request)
void CameraProxy::threadRpcCall(ThreadRpc &rpcRequest)
{
cameraDevice_->invokeMethod(&CameraDevice::call, &rpcRequest);
cameraDevice_->invokeMethod(&CameraDevice::call, ConnectionTypeQueued,
&rpcRequest);
rpcRequest.waitDelivery();
}

View file

@ -128,7 +128,8 @@ void EventNotifier::message(Message *msg)
if (msg->type() == Message::ThreadMoveMessage) {
if (enabled_) {
setEnabled(false);
invokeMethod(&EventNotifier::setEnabled, true);
invokeMethod(&EventNotifier::setEnabled,
ConnectionTypeQueued, true);
}
}

View file

@ -139,14 +139,15 @@ void Object::message(Message *msg)
}
/**
* \fn void Object::invokeMethod(void (T::*func)(Args...), Args... args)
* \fn void Object::invokeMethod()
* \brief Invoke a method asynchronously on an Object instance
* \param[in] func The object method to invoke
* \param[in] type Connection type for method invocation
* \param[in] args The method arguments
*
* This method invokes the member method \a func when control returns to the
* event loop of the object's thread. The method is executed in the object's
* thread with arguments \a args.
* This method invokes the member method \a func with arguments \a args, based
* on the connection \a type. Depending on the type, the method will be called
* synchronously in the same thread or asynchronously in the object's thread.
*
* Arguments \a args passed by value or reference are copied, while pointers
* are passed untouched. The caller shall ensure that any pointer argument

View file

@ -170,7 +170,8 @@ void Timer::message(Message *msg)
if (msg->type() == Message::ThreadMoveMessage) {
if (isRunning()) {
unregisterTimer();
invokeMethod(&Timer::registerTimer);
invokeMethod(&Timer::registerTimer,
ConnectionTypeQueued);
}
}

View file

@ -64,10 +64,11 @@ protected:
InvokedObject object;
/*
* Test that method invocation in the same thread goes through
* the event dispatcher.
* Test that queued method invocation in the same thread goes
* through the event dispatcher.
*/
object.invokeMethod(&InvokedObject::method, 42);
object.invokeMethod(&InvokedObject::method,
ConnectionTypeQueued, 42);
if (object.status() != InvokedObject::NoCall) {
cerr << "Method not invoked asynchronously" << endl;
@ -93,15 +94,16 @@ protected:
}
/*
* Move the object to a thread and verify that the method is
* delivered in the correct thread.
* Move the object to a thread and verify that auto method
* invocation is delivered in the correct thread.
*/
object.reset();
object.moveToThread(&thread_);
thread_.start();
object.invokeMethod(&InvokedObject::method, 42);
object.invokeMethod(&InvokedObject::method,
ConnectionTypeAuto, 42);
this_thread::sleep_for(chrono::milliseconds(100));
switch (object.status()) {