[libcamera-devel] [PATCH] android: camera_worker: Process all queued requests when stopping
Jacopo Mondi
jacopo at jmondi.org
Mon May 24 11:33:10 CEST 2021
Hi Laurent,
On Sun, May 23, 2021 at 05:33:42AM +0300, Laurent Pinchart wrote:
> When stopping the camera worker, queuedRequest() calls may have queued
> asynchronous function invocation messages to the worker thread, and some
> of those messages may not have been processed yet. The messages will
> stay in the thread's queue until the camera worker is restarted (when
> the camera service will start a new capture session). At that point,
> they will be dispatched, which will cause a crash due to the
> CaptureRequest passed to processRequest() having been deleted by
> CameraDevice::stop() calling descriptors_.clear().
>
> Fix this by forcing dispatching of all function invocation messages when
> stopping the camera worker thread. Note that this is inherently racy, as
> more queueRequest() calls may arrive from the camera service while we're
> stopping. This race condition will be addressed by a subsequent patch
> series.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> ---
> I haven't tested this patch, as I'm currently rebuilding a new Soraka
> image. Hiro, could you give it a try to see if it fixes the problem
> you've reported ?
> ---
> src/android/camera_worker.cpp | 14 ++++++++++----
> src/android/camera_worker.h | 6 ++++--
> 2 files changed, 14 insertions(+), 6 deletions(-)
>
> diff --git a/src/android/camera_worker.cpp b/src/android/camera_worker.cpp
> index 300ddde03645..9f727826e23f 100644
> --- a/src/android/camera_worker.cpp
> +++ b/src/android/camera_worker.cpp
> @@ -52,18 +52,24 @@ void CaptureRequest::queue()
> */
> CameraWorker::CameraWorker()
> {
> - worker_.moveToThread(&thread_);
> + worker_.moveToThread(this);
> }
>
> void CameraWorker::start()
> {
> - thread_.start();
> + Thread::start();
> }
>
> void CameraWorker::stop()
> {
> - thread_.exit();
> - thread_.wait();
> + exit();
> + wait();
> +}
> +
> +void CameraWorker::run()
> +{
> + exec();
> + dispatchMessages(Message::Type::InvokeMessage);
> }
>
> void CameraWorker::queueRequest(CaptureRequest *request)
> diff --git a/src/android/camera_worker.h b/src/android/camera_worker.h
> index 64b1658b61b4..e289ef9b8655 100644
> --- a/src/android/camera_worker.h
> +++ b/src/android/camera_worker.h
> @@ -42,7 +42,7 @@ private:
> std::unique_ptr<libcamera::Request> request_;
> };
>
> -class CameraWorker
> +class CameraWorker : private libcamera::Thread
There is one thing I don't get here
Now the whole CameraWorker runs in it own thread.
Before this change CameraWorker had a Worker that was run a separate
thread.
CameraDevice calls CameraWorker::queueRequest, which runs on a
different thread.
CameraWorker::queueRequest
void CameraWorker::queueRequest(CaptureRequest *request)
{
/* Async process the request on the worker which runs its own thread. */
worker_.invokeMethod(&Worker::processRequest, ConnectionTypeQueued,
request);
}
1) How does direct method calls on CameraWorker work now that it's a
Thread
2) If 1) is ok, then queueRequest should not need to call invokeMethod
on worker_ as it runs in the same thread CameraWorker itself.
Would it be possible to keep CameraWorker a simple class and make
Worker a thread ?
Thanks
j
> {
> public:
> CameraWorker();
> @@ -52,6 +52,9 @@ public:
>
> void queueRequest(CaptureRequest *request);
>
> +protected:
> + void run() override;
> +
> private:
> class Worker : public libcamera::Object
> {
> @@ -63,7 +66,6 @@ private:
> };
>
> Worker worker_;
> - libcamera::Thread thread_;
> };
>
> #endif /* __ANDROID_CAMERA_WORKER_H__ */
> --
> Regards,
>
> Laurent Pinchart
>
More information about the libcamera-devel
mailing list