Show a patch.

GET /api/1.1/patches/2705/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2705,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/2705/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/2705/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/1.1/projects/1/?format=api",
        "name": "libcamera",
        "link_name": "libcamera",
        "list_id": "libcamera_core",
        "list_email": "libcamera-devel@lists.libcamera.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": ""
    },
    "msgid": "<20200120002437.6633-19-laurent.pinchart@ideasonboard.com>",
    "date": "2020-01-20T00:24:36",
    "name": "[libcamera-devel,18/19] v4l2: Remove internal thread",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "a8b62a0b2eeceba70d2f4666632a6041d672e0e6",
    "submitter": {
        "id": 2,
        "url": "https://patchwork.libcamera.org/api/1.1/people/2/?format=api",
        "name": "Laurent Pinchart",
        "email": "laurent.pinchart@ideasonboard.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/2705/mbox/",
    "series": [
        {
            "id": 641,
            "url": "https://patchwork.libcamera.org/api/1.1/series/641/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=641",
            "date": "2020-01-20T00:24:19",
            "name": "Initial libcamera threading model",
            "version": 1,
            "mbox": "https://patchwork.libcamera.org/series/641/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/2705/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/2705/checks/",
    "tags": {},
    "headers": {
        "Return-Path": "<laurent.pinchart@ideasonboard.com>",
        "Received": [
            "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 8B34660808\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 20 Jan 2020 01:24:49 +0100 (CET)",
            "from pendragon.bb.dnainternet.fi (81-175-216-236.bb.dnainternet.fi\n\t[81.175.216.236])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 9ADD5563\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 20 Jan 2020 01:24:48 +0100 (CET)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1579479888;\n\tbh=pWndmu897QEt+JmjUPmC3KVu5gu85bjQmoA5v2SMfEc=;\n\th=From:To:Subject:Date:In-Reply-To:References:From;\n\tb=dXv/NXzwQ+qQzrbjvFJx4+O+61IkduKSajipni3N0RGyHqcJKddFbuqu7KCHnyV51\n\tVZ60ML8CXGcTQUQ2uFcs9zjJWpWhHgssKSfRIWgwXhC5FH8annUb7bG9fF6e6hnT/N\n\tdrLpiATcQu4wE1tOVZVhwhJYxBBKHBGAzoYo4xKE=",
        "From": "Laurent Pinchart <laurent.pinchart@ideasonboard.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Mon, 20 Jan 2020 02:24:36 +0200",
        "Message-Id": "<20200120002437.6633-19-laurent.pinchart@ideasonboard.com>",
        "X-Mailer": "git-send-email 2.24.1",
        "In-Reply-To": "<20200120002437.6633-1-laurent.pinchart@ideasonboard.com>",
        "References": "<20200120002437.6633-1-laurent.pinchart@ideasonboard.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[libcamera-devel] [PATCH 18/19] v4l2: Remove internal thread",
        "X-BeenThere": "libcamera-devel@lists.libcamera.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "<libcamera-devel.lists.libcamera.org>",
        "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>",
        "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>",
        "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>",
        "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>",
        "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>",
        "X-List-Received-Date": "Mon, 20 Jan 2020 00:24:51 -0000"
    },
    "content": "Now that libcamera creates threads internally and doesn't rely on an\napplication-provided event loop, remove the thread from the V4L2\ncompatibility layer. The split between the V4L2CameraProxy and\nV4L2Camera classes is still kept to separate the V4L2 adaptation from\ncamera operation. This may be further refactored later.\n\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\n src/v4l2/v4l2_camera.h           |  2 +-\n src/v4l2/v4l2_camera_proxy.cpp   | 43 ++++++++++------------------\n src/v4l2/v4l2_compat_manager.cpp | 48 +++++++++-----------------------\n src/v4l2/v4l2_compat_manager.h   | 13 ++-------\n 4 files changed, 31 insertions(+), 75 deletions(-)",
    "diff": "diff --git a/src/v4l2/v4l2_camera.h b/src/v4l2/v4l2_camera.h\nindex f1f04d9ef6ed..37bd358462db 100644\n--- a/src/v4l2/v4l2_camera.h\n+++ b/src/v4l2/v4l2_camera.h\n@@ -21,7 +21,7 @@\n \n using namespace libcamera;\n \n-class V4L2Camera : public Object\n+class V4L2Camera\n {\n public:\n \tstruct Buffer {\ndiff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp\nindex e58fd6a0d8b5..622520479be0 100644\n--- a/src/v4l2/v4l2_camera_proxy.cpp\n+++ b/src/v4l2/v4l2_camera_proxy.cpp\n@@ -41,8 +41,7 @@ int V4L2CameraProxy::open(bool nonBlocking)\n {\n \tLOG(V4L2Compat, Debug) << \"Servicing open\";\n \n-\tint ret = vcam_->invokeMethod(&V4L2Camera::open,\n-\t\t\t\t      ConnectionTypeBlocking);\n+\tint ret = vcam_->open();\n \tif (ret < 0) {\n \t\terrno = -ret;\n \t\treturn -1;\n@@ -50,8 +49,7 @@ int V4L2CameraProxy::open(bool nonBlocking)\n \n \tnonBlocking_ = nonBlocking;\n \n-\tvcam_->invokeMethod(&V4L2Camera::getStreamConfig,\n-\t\t\t    ConnectionTypeBlocking, &streamConfig_);\n+\tvcam_->getStreamConfig(&streamConfig_);\n \tsetFmtFromConfig(streamConfig_);\n \tsizeimage_ = calculateSizeImage(streamConfig_);\n \n@@ -72,7 +70,7 @@ void V4L2CameraProxy::close()\n \tif (--refcount_ > 0)\n \t\treturn;\n \n-\tvcam_->invokeMethod(&V4L2Camera::close, ConnectionTypeBlocking);\n+\tvcam_->close();\n }\n \n void *V4L2CameraProxy::mmap(void *addr, size_t length, int prot, int flags,\n@@ -284,11 +282,9 @@ int V4L2CameraProxy::vidioc_s_fmt(struct v4l2_format *arg)\n \ttryFormat(arg);\n \n \tSize size(arg->fmt.pix.width, arg->fmt.pix.height);\n-\tint ret = vcam_->invokeMethod(&V4L2Camera::configure,\n-\t\t\t\t      ConnectionTypeBlocking,\n-\t\t\t\t      &streamConfig_, size,\n-\t\t\t\t      v4l2ToDrm(arg->fmt.pix.pixelformat),\n-\t\t\t\t      bufferCount_);\n+\tint ret = vcam_->configure(&streamConfig_, size,\n+\t\t\t\t   v4l2ToDrm(arg->fmt.pix.pixelformat),\n+\t\t\t\t   bufferCount_);\n \tif (ret < 0)\n \t\treturn -EINVAL;\n \n@@ -319,13 +315,12 @@ int V4L2CameraProxy::freeBuffers()\n {\n \tLOG(V4L2Compat, Debug) << \"Freeing libcamera bufs\";\n \n-\tint ret = vcam_->invokeMethod(&V4L2Camera::streamOff,\n-\t\t\t\t      ConnectionTypeBlocking);\n+\tint ret = vcam_->streamOff();\n \tif (ret < 0) {\n \t\tLOG(V4L2Compat, Error) << \"Failed to stop stream\";\n \t\treturn ret;\n \t}\n-\tvcam_->invokeMethod(&V4L2Camera::freeBuffers, ConnectionTypeBlocking);\n+\tvcam_->freeBuffers();\n \tbufferCount_ = 0;\n \n \treturn 0;\n@@ -349,11 +344,9 @@ int V4L2CameraProxy::vidioc_reqbufs(struct v4l2_requestbuffers *arg)\n \t\treturn freeBuffers();\n \n \tSize size(curV4L2Format_.fmt.pix.width, curV4L2Format_.fmt.pix.height);\n-\tret = vcam_->invokeMethod(&V4L2Camera::configure,\n-\t\t\t\t  ConnectionTypeBlocking,\n-\t\t\t\t  &streamConfig_, size,\n-\t\t\t\t  v4l2ToDrm(curV4L2Format_.fmt.pix.pixelformat),\n-\t\t\t\t  arg->count);\n+\tret = vcam_->configure(&streamConfig_, size,\n+\t\t\t       v4l2ToDrm(curV4L2Format_.fmt.pix.pixelformat),\n+\t\t\t       arg->count);\n \tif (ret < 0)\n \t\treturn -EINVAL;\n \n@@ -366,8 +359,7 @@ int V4L2CameraProxy::vidioc_reqbufs(struct v4l2_requestbuffers *arg)\n \targ->count = streamConfig_.bufferCount;\n \tbufferCount_ = arg->count;\n \n-\tret = vcam_->invokeMethod(&V4L2Camera::allocBuffers,\n-\t\t\t\t  ConnectionTypeBlocking, arg->count);\n+\tret = vcam_->allocBuffers(arg->count);\n \tif (ret < 0) {\n \t\targ->count = 0;\n \t\treturn ret;\n@@ -415,8 +407,7 @@ int V4L2CameraProxy::vidioc_qbuf(struct v4l2_buffer *arg)\n \t    arg->index >= bufferCount_)\n \t\treturn -EINVAL;\n \n-\tint ret = vcam_->invokeMethod(&V4L2Camera::qbuf, ConnectionTypeBlocking,\n-\t\t\t\t      arg->index);\n+\tint ret = vcam_->qbuf(arg->index);\n \tif (ret < 0)\n \t\treturn ret;\n \n@@ -459,10 +450,7 @@ int V4L2CameraProxy::vidioc_streamon(int *arg)\n \tif (!validateBufferType(*arg))\n \t\treturn -EINVAL;\n \n-\tint ret = vcam_->invokeMethod(&V4L2Camera::streamOn,\n-\t\t\t\t      ConnectionTypeBlocking);\n-\n-\treturn ret;\n+\treturn vcam_->streamOn();\n }\n \n int V4L2CameraProxy::vidioc_streamoff(int *arg)\n@@ -472,8 +460,7 @@ int V4L2CameraProxy::vidioc_streamoff(int *arg)\n \tif (!validateBufferType(*arg))\n \t\treturn -EINVAL;\n \n-\tint ret = vcam_->invokeMethod(&V4L2Camera::streamOff,\n-\t\t\t\t      ConnectionTypeBlocking);\n+\tint ret = vcam_->streamOff();\n \n \tfor (struct v4l2_buffer &buf : buffers_)\n \t\tbuf.flags &= ~(V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE);\ndiff --git a/src/v4l2/v4l2_compat_manager.cpp b/src/v4l2/v4l2_compat_manager.cpp\nindex f5a7b2ac4229..961d06b3e39a 100644\n--- a/src/v4l2/v4l2_compat_manager.cpp\n+++ b/src/v4l2/v4l2_compat_manager.cpp\n@@ -37,7 +37,7 @@ void get_symbol(T &func, const char *name)\n } /* namespace */\n \n V4L2CompatManager::V4L2CompatManager()\n-\t: cm_(nullptr), initialized_(false)\n+\t: cm_(nullptr)\n {\n \tget_symbol(fops_.openat, \"openat\");\n \tget_symbol(fops_.dup, \"dup\");\n@@ -52,24 +52,15 @@ V4L2CompatManager::~V4L2CompatManager()\n \tdevices_.clear();\n \tmmaps_.clear();\n \n-\tif (isRunning()) {\n-\t\texit(0);\n-\t\t/* \\todo Wait with a timeout, just in case. */\n-\t\twait();\n+\tif (cm_) {\n+\t\tproxies_.clear();\n+\t\tcm_->stop();\n+\t\tdelete cm_;\n+\t\tcm_ = nullptr;\n \t}\n }\n \n-int V4L2CompatManager::init()\n-{\n-\tstart();\n-\n-\tMutexLocker locker(mutex_);\n-\tcv_.wait(locker, [&] { return initialized_; });\n-\n-\treturn 0;\n-}\n-\n-void V4L2CompatManager::run()\n+int V4L2CompatManager::start()\n {\n \tcm_ = new CameraManager();\n \n@@ -77,7 +68,9 @@ void V4L2CompatManager::run()\n \tif (ret) {\n \t\tLOG(V4L2Compat, Error) << \"Failed to start camera manager: \"\n \t\t\t\t       << strerror(-ret);\n-\t\treturn;\n+\t\tdelete cm_;\n+\t\tcm_ = nullptr;\n+\t\treturn ret;\n \t}\n \n \tLOG(V4L2Compat, Debug) << \"Started camera manager\";\n@@ -93,22 +86,7 @@ void V4L2CompatManager::run()\n \t\t++index;\n \t}\n \n-\t/*\n-\t * libcamera has been initialized. Unlock the init() caller as we're\n-\t * now ready to handle calls from the framework.\n-\t */\n-\tmutex_.lock();\n-\tinitialized_ = true;\n-\tmutex_.unlock();\n-\tcv_.notify_one();\n-\n-\t/* Now start processing events and messages. */\n-\texec();\n-\n-\tproxies_.clear();\n-\tcm_->stop();\n-\tdelete cm_;\n-\tcm_ = nullptr;\n+\treturn 0;\n }\n \n V4L2CompatManager *V4L2CompatManager::instance()\n@@ -159,8 +137,8 @@ int V4L2CompatManager::openat(int dirfd, const char *path, int oflag, mode_t mod\n \t    major(statbuf.st_rdev) != 81)\n \t\treturn fd;\n \n-\tif (!isRunning())\n-\t\tinit();\n+\tif (!cm_)\n+\t\tstart();\n \n \tret = getCameraIndex(fd);\n \tif (ret < 0) {\ndiff --git a/src/v4l2/v4l2_compat_manager.h b/src/v4l2/v4l2_compat_manager.h\nindex d51b5953d930..872c7c3b10e8 100644\n--- a/src/v4l2/v4l2_compat_manager.h\n+++ b/src/v4l2/v4l2_compat_manager.h\n@@ -8,22 +8,19 @@\n #ifndef __V4L2_COMPAT_MANAGER_H__\n #define __V4L2_COMPAT_MANAGER_H__\n \n-#include <condition_variable>\n #include <fcntl.h>\n #include <map>\n #include <memory>\n-#include <mutex>\n #include <sys/types.h>\n #include <vector>\n \n #include <libcamera/camera_manager.h>\n \n-#include \"thread.h\"\n #include \"v4l2_camera_proxy.h\"\n \n using namespace libcamera;\n \n-class V4L2CompatManager : public Thread\n+class V4L2CompatManager\n {\n public:\n \tstruct FileOperations {\n@@ -46,8 +43,6 @@ public:\n \n \tstatic V4L2CompatManager *instance();\n \n-\tint init();\n-\n \tV4L2CameraProxy *getProxy(int fd);\n \tconst FileOperations &fops() const { return fops_; }\n \n@@ -64,17 +59,13 @@ private:\n \tV4L2CompatManager();\n \t~V4L2CompatManager();\n \n-\tvoid run() override;\n+\tint start();\n \tint getCameraIndex(int fd);\n \n \tFileOperations fops_;\n \n \tCameraManager *cm_;\n \n-\tstd::mutex mutex_;\n-\tstd::condition_variable cv_;\n-\tbool initialized_;\n-\n \tstd::vector<std::unique_ptr<V4L2CameraProxy>> proxies_;\n \tstd::map<int, V4L2CameraProxy *> devices_;\n \tstd::map<void *, V4L2CameraProxy *> mmaps_;\n",
    "prefixes": [
        "libcamera-devel",
        "18/19"
    ]
}