[{"id":3580,"web_url":"https://patchwork.libcamera.org/comment/3580/","msgid":"<20200122163918.GZ1124294@oden.dyn.berto.se>","date":"2020-01-22T16:39:18","subject":"Re: [libcamera-devel] [PATCH 18/19] v4l2: Remove internal thread","submitter":{"id":5,"url":"https://patchwork.libcamera.org/api/people/5/","name":"Niklas Söderlund","email":"niklas.soderlund@ragnatech.se"},"content":"Hi Laurent,\n\nThanks for your work.\n\nOn 2020-01-20 02:24:36 +0200, Laurent Pinchart wrote:\n> Now that libcamera creates threads internally and doesn't rely on an\n> application-provided event loop, remove the thread from the V4L2\n> compatibility layer. The split between the V4L2CameraProxy and\n> V4L2Camera classes is still kept to separate the V4L2 adaptation from\n> camera operation. This may be further refactored later.\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nReviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n\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(-)\n> \n> diff --git a/src/v4l2/v4l2_camera.h b/src/v4l2/v4l2_camera.h\n> index 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 {\n> diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp\n> index 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);\n> diff --git a/src/v4l2/v4l2_compat_manager.cpp b/src/v4l2/v4l2_compat_manager.cpp\n> index 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) {\n> diff --git a/src/v4l2/v4l2_compat_manager.h b/src/v4l2/v4l2_compat_manager.h\n> index 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> -- \n> Regards,\n> \n> Laurent Pinchart\n> \n> _______________________________________________\n> libcamera-devel mailing list\n> libcamera-devel@lists.libcamera.org\n> https://lists.libcamera.org/listinfo/libcamera-devel","headers":{"Return-Path":"<niklas.soderlund@ragnatech.se>","Received":["from mail-lj1-x243.google.com (mail-lj1-x243.google.com\n\t[IPv6:2a00:1450:4864:20::243])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3568D60804\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 22 Jan 2020 17:39:20 +0100 (CET)","by mail-lj1-x243.google.com with SMTP id o13so7563757ljg.4\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 22 Jan 2020 08:39:20 -0800 (PST)","from localhost (h-93-159.A463.priv.bahnhof.se. [46.59.93.159])\n\tby smtp.gmail.com with ESMTPSA id\n\ty8sm20595797lji.56.2020.01.22.08.39.18\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tWed, 22 Jan 2020 08:39:19 -0800 (PST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=ragnatech-se.20150623.gappssmtp.com; s=20150623;\n\th=date:from:to:cc:subject:message-id:references:mime-version\n\t:content-disposition:content-transfer-encoding:in-reply-to;\n\tbh=+hS0CXDkQHD11SoM1suqdNCHyh7K7cSTzkqjnHiL71s=;\n\tb=RuzfXYM6FotEPN1IT/sjKtKSOnr8tePTECbSFiPRibbsNEOaVxRTgY2gpqJf62sN2D\n\tADxPFaV9u6bWv3M9bdzSUyaTAR41BonqOOAhV/z4T7oIrZG6Pz+JusPQZzsZp8GuUyPO\n\tqrnuaK2bL1kuDNkFICZ5xU9iSCC+qQKaLDv84D7b+HtbTy5hqSaNlpQKvBs4wyznCSk6\n\tjQHpf/MBdan6Ohrg8545KDofoyORuvdVnyLjfPrpSc3kuJh3oiLjMRRHKtfZW7MGIUZV\n\tMcgKjVij6VjGJCJ/iBqMkj/o9ueegChuOaYbtOKqDmhdAL5P/wY39nmrWmIAkzaCujdc\n\tvU7g==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:date:from:to:cc:subject:message-id:references\n\t:mime-version:content-disposition:content-transfer-encoding\n\t:in-reply-to;\n\tbh=+hS0CXDkQHD11SoM1suqdNCHyh7K7cSTzkqjnHiL71s=;\n\tb=SeZ9cw7cXKJBN99QljltNk/z9qARVM//91mxdQUKfHAzFPZ7thMovfx6yyXAVZUQK9\n\t63cL3R+cRcdWuAukFc8l8zrZkSe/DJR6IrH4UrmouE2g5hhaYJWDMkAv0iWo4oPflWsx\n\t1EIilWswodWhNRUK4JszbNQjKIb8wzLXP0bva+fMptSusS6j/ySJSoIBPr4FF0evViEU\n\twI/yIQNjbV9zzhLJ/clLA/k1KToHhWiSfqKHOvxvco6cMBooYFagbaBt2KWL2GAFBMLn\n\tB/AMvI/fdvcXpTa1KsuOmL+1HxKA8np3HuX4h7owBM6bY9WBBav2ZgPYEir+J4afhNLQ\n\tOOTw==","X-Gm-Message-State":"APjAAAVeJIh+51scyIleyoyQTpQrdLNB/gGc/LRZdiC7SkdbYdsUHuMG\n\tlnFZUM+VIOYgbNSik8CN4VatGQ==","X-Google-Smtp-Source":"APXvYqz5tNC/YYqR84wbF+uY/Wpk2Vpq11/EFwyC4KsFuaXJgtfE5wGiluKoFsUA7je9F6m6bMC5RQ==","X-Received":"by 2002:a2e:2283:: with SMTP id\n\ti125mr20744400lji.244.1579711159589; \n\tWed, 22 Jan 2020 08:39:19 -0800 (PST)","Date":"Wed, 22 Jan 2020 17:39:18 +0100","From":"Niklas =?iso-8859-1?q?S=F6derlund?= <niklas.soderlund@ragnatech.se>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Message-ID":"<20200122163918.GZ1124294@oden.dyn.berto.se>","References":"<20200120002437.6633-1-laurent.pinchart@ideasonboard.com>\n\t<20200120002437.6633-19-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=iso-8859-1","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20200120002437.6633-19-laurent.pinchart@ideasonboard.com>","Subject":"Re: [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":"Wed, 22 Jan 2020 16:39:20 -0000"}}]