Message ID | 20191028104913.14985-8-laurent.pinchart@ideasonboard.com |
---|---|
State | Accepted |
Headers | show |
Series |
|
Related | show |
Hi Jacopo, Thanks for your work. On 2019-10-28 12:49:11 +0200, Laurent Pinchart wrote: > From: Jacopo Mondi <jacopo@jmondi.org> > > 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> > --- > include/libcamera/object.h | 5 ++--- > src/android/camera_proxy.cpp | 3 ++- > src/libcamera/event_notifier.cpp | 3 ++- > src/libcamera/object.cpp | 9 +++++---- > src/libcamera/timer.cpp | 3 ++- > test/object-invoke.cpp | 14 ++++++++------ > 6 files changed, 21 insertions(+), 16 deletions(-) > > diff --git a/include/libcamera/object.h b/include/libcamera/object.h > index 603a229288c2..91b56596c9db 100644 > --- a/include/libcamera/object.h > +++ b/include/libcamera/object.h > @@ -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); > diff --git a/src/android/camera_proxy.cpp b/src/android/camera_proxy.cpp > index 4f5c0a024903..43e1e1c3af53 100644 > --- a/src/android/camera_proxy.cpp > +++ b/src/android/camera_proxy.cpp > @@ -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(); > } > diff --git a/src/libcamera/event_notifier.cpp b/src/libcamera/event_notifier.cpp > index 687969b0a8d1..4326b0b413e2 100644 > --- a/src/libcamera/event_notifier.cpp > +++ b/src/libcamera/event_notifier.cpp > @@ -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); > } > } > > diff --git a/src/libcamera/object.cpp b/src/libcamera/object.cpp > index 509b2ebac537..db2c6f68fbc8 100644 > --- a/src/libcamera/object.cpp > +++ b/src/libcamera/object.cpp > @@ -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 > diff --git a/src/libcamera/timer.cpp b/src/libcamera/timer.cpp > index ddb20954afa7..4c68883204e8 100644 > --- a/src/libcamera/timer.cpp > +++ b/src/libcamera/timer.cpp > @@ -170,7 +170,8 @@ void Timer::message(Message *msg) > if (msg->type() == Message::ThreadMoveMessage) { > if (isRunning()) { > unregisterTimer(); > - invokeMethod(&Timer::registerTimer); > + invokeMethod(&Timer::registerTimer, > + ConnectionTypeQueued); > } > } > > diff --git a/test/object-invoke.cpp b/test/object-invoke.cpp > index 37a274402e6d..f6ae2604db76 100644 > --- a/test/object-invoke.cpp > +++ b/test/object-invoke.cpp > @@ -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()) { > -- > Regards, > > Laurent Pinchart > > _______________________________________________ > libcamera-devel mailing list > libcamera-devel@lists.libcamera.org > https://lists.libcamera.org/listinfo/libcamera-devel
diff --git a/include/libcamera/object.h b/include/libcamera/object.h index 603a229288c2..91b56596c9db 100644 --- a/include/libcamera/object.h +++ b/include/libcamera/object.h @@ -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); diff --git a/src/android/camera_proxy.cpp b/src/android/camera_proxy.cpp index 4f5c0a024903..43e1e1c3af53 100644 --- a/src/android/camera_proxy.cpp +++ b/src/android/camera_proxy.cpp @@ -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(); } diff --git a/src/libcamera/event_notifier.cpp b/src/libcamera/event_notifier.cpp index 687969b0a8d1..4326b0b413e2 100644 --- a/src/libcamera/event_notifier.cpp +++ b/src/libcamera/event_notifier.cpp @@ -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); } } diff --git a/src/libcamera/object.cpp b/src/libcamera/object.cpp index 509b2ebac537..db2c6f68fbc8 100644 --- a/src/libcamera/object.cpp +++ b/src/libcamera/object.cpp @@ -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 diff --git a/src/libcamera/timer.cpp b/src/libcamera/timer.cpp index ddb20954afa7..4c68883204e8 100644 --- a/src/libcamera/timer.cpp +++ b/src/libcamera/timer.cpp @@ -170,7 +170,8 @@ void Timer::message(Message *msg) if (msg->type() == Message::ThreadMoveMessage) { if (isRunning()) { unregisterTimer(); - invokeMethod(&Timer::registerTimer); + invokeMethod(&Timer::registerTimer, + ConnectionTypeQueued); } } diff --git a/test/object-invoke.cpp b/test/object-invoke.cpp index 37a274402e6d..f6ae2604db76 100644 --- a/test/object-invoke.cpp +++ b/test/object-invoke.cpp @@ -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()) {