Files
external_libcamera/src/android/camera_worker.h
Laurent Pinchart 7de2daf653 android: camera_worker: Process all queued requests when stopping
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@ideasonboard.com>
Tested-by: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2021-05-24 15:06:05 +03:00

72 lines
1.4 KiB
C++

/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2020, Google Inc.
*
* camera_worker.h - Process capture requests on behalf of the Camera HAL
*/
#ifndef __ANDROID_CAMERA_WORKER_H__
#define __ANDROID_CAMERA_WORKER_H__
#include <memory>
#include <libcamera/buffer.h>
#include <libcamera/camera.h>
#include <libcamera/object.h>
#include <libcamera/request.h>
#include <libcamera/stream.h>
#include "libcamera/internal/thread.h"
class CameraDevice;
class CaptureRequest
{
public:
CaptureRequest(libcamera::Camera *camera);
const std::vector<int> &fences() const { return acquireFences_; }
libcamera::ControlList &controls() { return request_->controls(); }
const libcamera::ControlList &metadata() const
{
return request_->metadata();
}
unsigned long cookie() const { return request_->cookie(); }
void addBuffer(libcamera::Stream *stream,
libcamera::FrameBuffer *buffer, int fence);
void queue();
private:
libcamera::Camera *camera_;
std::vector<int> acquireFences_;
std::unique_ptr<libcamera::Request> request_;
};
class CameraWorker : private libcamera::Thread
{
public:
CameraWorker();
void start();
void stop();
void queueRequest(CaptureRequest *request);
protected:
void run() override;
private:
class Worker : public libcamera::Object
{
public:
void processRequest(CaptureRequest *request);
private:
int waitFence(int fence);
};
Worker worker_;
};
#endif /* __ANDROID_CAMERA_WORKER_H__ */