[{"id":4849,"web_url":"https://patchwork.libcamera.org/comment/4849/","msgid":"<20200519134420.GF470768@oden.dyn.berto.se>","date":"2020-05-19T13:44:20","subject":"Re: [libcamera-devel] [PATCH 1/3] libcamera: file_descriptor:\n\tImplement move semantics for constructor","submitter":{"id":5,"url":"https://patchwork.libcamera.org/api/people/5/","name":"Niklas Söderlund","email":"niklas.soderlund@ragnatech.se"},"content":"Hi Laurent,\n\nTanks for your work.\n\nOn 2020-05-18 19:48:02 +0300, Laurent Pinchart wrote:\n> The FileDescriptor class, when constructed from a numerical file\n> descriptor, duplicates the file descriptor and takes ownership of the\n> copy. The caller has to close the original file descriptor manually if\n> needed. This is inefficient as the dup() and close() calls could be\n> avoided, but can also lead to resource leakage, as recently shown by\n> commit 353fc4c22322 (\"libcamera: v4l2_videodevice: Fix dangling file\n> descriptor\").\n> \n> In an attempt to solve this problem, implement move semantics for the\n> FileDescriptor constructor. The constructor taking a numerical file\n> descriptor is split in two variants:\n> \n> - A \"fd copy\" constructor that takes a const lvalue reference to a\n>   numerical file descriptor and duplicates it (corresponding to the\n>   current behaviour).\n> - A \"fd move\" constructor that takes a rvalue reference to a numerical\n>   file descriptor and takes ownership of it.\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nReviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n\n> ---\n>  include/libcamera/file_descriptor.h |  5 +-\n>  src/libcamera/file_descriptor.cpp   | 85 ++++++++++++++++++++++-------\n>  2 files changed, 67 insertions(+), 23 deletions(-)\n> \n> diff --git a/include/libcamera/file_descriptor.h b/include/libcamera/file_descriptor.h\n> index 8612f86511a1..d514aac7697b 100644\n> --- a/include/libcamera/file_descriptor.h\n> +++ b/include/libcamera/file_descriptor.h\n> @@ -14,7 +14,8 @@ namespace libcamera {\n>  class FileDescriptor final\n>  {\n>  public:\n> -\texplicit FileDescriptor(int fd = -1);\n> +\texplicit FileDescriptor(const int &fd = -1);\n> +\texplicit FileDescriptor(int &&fd);\n>  \tFileDescriptor(const FileDescriptor &other);\n>  \tFileDescriptor(FileDescriptor &&other);\n>  \t~FileDescriptor();\n> @@ -30,7 +31,7 @@ private:\n>  \tclass Descriptor\n>  \t{\n>  \tpublic:\n> -\t\tDescriptor(int fd);\n> +\t\tDescriptor(int fd, bool duplicate);\n>  \t\t~Descriptor();\n>  \n>  \t\tint fd() const { return fd_; }\n> diff --git a/src/libcamera/file_descriptor.cpp b/src/libcamera/file_descriptor.cpp\n> index ee60064bce6e..640e66e6d168 100644\n> --- a/src/libcamera/file_descriptor.cpp\n> +++ b/src/libcamera/file_descriptor.cpp\n> @@ -33,43 +33,81 @@ LOG_DEFINE_CATEGORY(FileDescriptor)\n>   * shared with all FileDescriptor instances constructed as copies.\n>   *\n>   * When constructed from a numerical file descriptor, the FileDescriptor\n> - * instance duplicates the file descriptor and wraps the duplicate as a\n> - * Descriptor. The copy constructor and assignment operator create copies that\n> - * share the Descriptor, while the move versions of those methods additionally\n> - * make the other FileDescriptor invalid. When the last FileDescriptor that\n> - * references a Descriptor is destroyed, the file descriptor is closed.\n> - *\n> - * The numerical file descriptor is available through the fd() method. As\n> - * constructing a FileDescriptor from a numerical file descriptor duplicates\n> - * the file descriptor, the value returned by fd() will be different than the\n> - * value passed to the constructor. All FileDescriptor instances created as\n> - * copies of a FileDescriptor will report the same fd() value. Callers can\n> - * perform operations on the fd(), but shall never close it manually.\n> + * instance either duplicates or takes over the file descriptor:\n> + *\n> + * - The FileDescriptor(const int &) constructor duplicates the numerical file\n> + *   descriptor and wraps the duplicate in a Descriptor. The caller is\n> + *   responsible for closing the original file descriptor, and the value\n> + *   returned by fd() will be different from the value passed to the\n> + *   constructor.\n> + *\n> + * - The FileDescriptor(int &&) constructor takes over the numerical file\n> + *   descriptor and wraps it in a Descriptor. The caller is shall not touch the\n> + *   original file descriptor once the function returns, and the value returned\n> + *   by fd() will be identical to the value passed to the constructor.\n> + *\n> + * The copy constructor and assignment operator create copies that share the\n> + * Descriptor, while the move versions of those methods additionally make the\n> + * other FileDescriptor invalid. When the last FileDescriptor that references a\n> + * Descriptor is destroyed, the file descriptor is closed.\n> + *\n> + * The numerical file descriptor is available through the fd() method. All\n> + * FileDescriptor instances created as copies of a FileDescriptor will report\n> + * the same fd() value. Callers can perform operations on the fd(), but shall\n> + * never close it manually.\n>   */\n>  \n>  /**\n> - * \\brief Create a FileDescriptor wrapping a copy of a given \\a fd\n> + * \\brief Create a FileDescriptor copying a given \\a fd\n>   * \\param[in] fd File descriptor\n>   *\n> - * Constructing a FileDescriptor from a numerical file descriptor duplicates the\n> - * \\a fd and takes ownership of the copy. The original \\a fd is left untouched,\n> - * and the caller is responsible for closing it when appropriate. The duplicated\n> - * file descriptor will be closed automatically when all FileDescriptor\n> - * instances that reference it are destroyed.\n> + * Construct a FileDescriptor from a numerical file descriptor by duplicating\n> + * the \\a fd, and take ownership of the copy. The original \\a fd is left\n> + * untouched, and the caller is responsible for closing it when appropriate.\n> + * The duplicated file descriptor will be closed automatically when all\n> + * FileDescriptor instances that reference it are destroyed.\n>   *\n>   * If the \\a fd is negative, the FileDescriptor is constructed as invalid and\n>   * the fd() method will return -1.\n>   */\n> -FileDescriptor::FileDescriptor(int fd)\n> +FileDescriptor::FileDescriptor(const int &fd)\n>  {\n>  \tif (fd < 0)\n>  \t\treturn;\n>  \n> -\tfd_ = std::make_shared<Descriptor>(fd);\n> +\tfd_ = std::make_shared<Descriptor>(fd, true);\n>  \tif (fd_->fd() < 0)\n>  \t\tfd_.reset();\n>  }\n>  \n> +/**\n> + * \\brief Create a FileDescriptor taking ownership of a given \\a fd\n> + * \\param[in] fd File descriptor\n> + *\n> + * Construct a FileDescriptor from a numerical file descriptor by taking\n> + * ownership of the \\a fd. The original \\a fd is set to -1 and shall not be\n> + * touched by the caller anymore. In particular, the caller shall not close the\n> + * original \\a fd manually. The duplicated file descriptor will be closed\n> + * automatically when all FileDescriptor instances that reference it are\n> + * destroyed.\n> + *\n> + * If the \\a fd is negative, the FileDescriptor is constructed as invalid and\n> + * the fd() method will return -1.\n> + */\n> +FileDescriptor::FileDescriptor(int &&fd)\n> +{\n> +\tif (fd < 0)\n> +\t\treturn;\n> +\n> +\tfd_ = std::make_shared<Descriptor>(fd, false);\n> +\t/*\n> +\t * The Descriptor constructor can't have failed here, as it took over\n> +\t * the fd without duplicating it. Just set the original fd to -1 to\n> +\t * implement move semantics.\n> +\t */\n> +\tfd = -1;\n> +}\n> +\n>  /**\n>   * \\brief Copy constructor, create a FileDescriptor from a copy of \\a other\n>   * \\param[in] other The other FileDescriptor\n> @@ -183,8 +221,13 @@ FileDescriptor FileDescriptor::dup() const\n>  \treturn FileDescriptor(fd());\n>  }\n>  \n> -FileDescriptor::Descriptor::Descriptor(int fd)\n> +FileDescriptor::Descriptor::Descriptor(int fd, bool duplicate)\n>  {\n> +\tif (!duplicate) {\n> +\t\tfd_ = fd;\n> +\t\treturn;\n> +\t}\n> +\n>  \t/* Failing to dup() a fd should not happen and is fatal. */\n>  \tfd_ = ::dup(fd);\n>  \tif (fd_ == -1) {\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-x242.google.com (mail-lj1-x242.google.com\n\t[IPv6:2a00:1450:4864:20::242])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 96B8B603D9\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 19 May 2020 15:44:22 +0200 (CEST)","by mail-lj1-x242.google.com with SMTP id z18so5570144lji.12\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 19 May 2020 06:44:22 -0700 (PDT)","from localhost (h-209-203.A463.priv.bahnhof.se. [155.4.209.203])\n\tby smtp.gmail.com with ESMTPSA id\n\tr9sm7544888ljg.69.2020.05.19.06.44.20\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tTue, 19 May 2020 06:44:20 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected)\n\theader.d=ragnatech-se.20150623.gappssmtp.com\n\theader.i=@ragnatech-se.20150623.gappssmtp.com header.b=\"GHFcUO4q\"; \n\tdkim-atps=neutral","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=sdT52BxVIbvUOu7o+G4qeGeCgkmelil9s1RhulmBS9U=;\n\tb=GHFcUO4qyHyuCZn4pgsGH2NgURt2CMOrlmMtuWTwC5LfqY987UhbNxM6vlor1wETwd\n\tQk508TTkaYY6sPjxyTt45aq6+cB21Dmspmmr8cmVjErvcZLgCX/idp5xKKiXKFvA0UV0\n\tmb78C1m0klgyDL9+nOSuqsPBAm01fwkikUwnRdiRSud6Q1l3pQbarfM+z0Te8u5bgjFP\n\tbZLn/TVCKOd84NeRnR8juL8lqJQh5Vo29cVMh1MAoEvT7QZgE/D2MnRFNULdRDd/ldUb\n\tbxN26SOGhZr+djBjM5Fa213xAX3Mi7Y913UQbSLjJIytrJxWqYZbwHI1oC+gpM9iGe6h\n\tUCRg==","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=sdT52BxVIbvUOu7o+G4qeGeCgkmelil9s1RhulmBS9U=;\n\tb=eLcYex1FkTGpVhRmGAylxdh2WLY/tQ2XoO7b6g35UUjRt11XfGJtCTQ40AnM8mkX2G\n\tcEtaXez78iEi6qEbuit5QoV/njGyue32Aabr1Bq5Ffge1IvPBHbwQSiTzNydvpfT+ZYQ\n\tW2l1dq3FnCBjk4HxXKDrtXTjYqspx+kCEPne++tcxBgvmhkvLgMlugwi3jVqrO+wZmas\n\tt9jeAw5KGJZ0TdmIjVw4vGcLZiMw8J9xct/yidAkzQG3rrNZDNewjWBGD8xnY9GsL3VY\n\tarPyf6Oh+a3hfJ4G+519QlPXo3XV91ldMsyezsUVf2cALKAR5TTb6hCClzpj9XLRv8Nk\n\tDx4g==","X-Gm-Message-State":"AOAM533/UlnRwrz0ja2x1KSeIhe+YtLEyEtrF61DeQ6WKdgc5zHH4lF5\n\tTcMCj8IXj0YBN1JUmoT21GBcsss3hsNIXg==","X-Google-Smtp-Source":"ABdhPJxMDdSERkVaOvv+ewijTHja3oVxkwayjuSydoTar+KGbPagmLmIG+irhR049me4KdA/py01cA==","X-Received":"by 2002:a2e:9ada:: with SMTP id\n\tp26mr14281216ljj.14.1589895861525; \n\tTue, 19 May 2020 06:44:21 -0700 (PDT)","Date":"Tue, 19 May 2020 15:44:20 +0200","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":"<20200519134420.GF470768@oden.dyn.berto.se>","References":"<20200518164804.10088-1-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":"<20200518164804.10088-1-laurent.pinchart@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH 1/3] libcamera: file_descriptor:\n\tImplement move semantics for constructor","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":"Tue, 19 May 2020 13:44:22 -0000"}},{"id":4865,"web_url":"https://patchwork.libcamera.org/comment/4865/","msgid":"<CAEmqJPriMXMET2UW0Q0EXfaA=9hYLZr2-_nfHyTGfRPn-wfU=Q@mail.gmail.com>","date":"2020-05-19T14:40:44","subject":"Re: [libcamera-devel] [PATCH 1/3] libcamera: file_descriptor:\n\tImplement move semantics for constructor","submitter":{"id":34,"url":"https://patchwork.libcamera.org/api/people/34/","name":"Naushir Patuck","email":"naush@raspberrypi.com"},"content":"Hi Laurent,\n\nThank you for the patch.  This does fix the underlying problem for me.\n\nOn Mon, 18 May 2020 at 17:48, Laurent Pinchart\n<laurent.pinchart@ideasonboard.com> wrote:\n>\n> The FileDescriptor class, when constructed from a numerical file\n> descriptor, duplicates the file descriptor and takes ownership of the\n> copy. The caller has to close the original file descriptor manually if\n> needed. This is inefficient as the dup() and close() calls could be\n> avoided, but can also lead to resource leakage, as recently shown by\n> commit 353fc4c22322 (\"libcamera: v4l2_videodevice: Fix dangling file\n> descriptor\").\n>\n> In an attempt to solve this problem, implement move semantics for the\n> FileDescriptor constructor. The constructor taking a numerical file\n> descriptor is split in two variants:\n>\n> - A \"fd copy\" constructor that takes a const lvalue reference to a\n>   numerical file descriptor and duplicates it (corresponding to the\n>   current behaviour).\n> - A \"fd move\" constructor that takes a rvalue reference to a numerical\n>   file descriptor and takes ownership of it.\n>\n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nReviewed-by: Naushir Patuck <naush@raspberrypi.com>\n\n> ---\n>  include/libcamera/file_descriptor.h |  5 +-\n>  src/libcamera/file_descriptor.cpp   | 85 ++++++++++++++++++++++-------\n>  2 files changed, 67 insertions(+), 23 deletions(-)\n>\n> diff --git a/include/libcamera/file_descriptor.h b/include/libcamera/file_descriptor.h\n> index 8612f86511a1..d514aac7697b 100644\n> --- a/include/libcamera/file_descriptor.h\n> +++ b/include/libcamera/file_descriptor.h\n> @@ -14,7 +14,8 @@ namespace libcamera {\n>  class FileDescriptor final\n>  {\n>  public:\n> -       explicit FileDescriptor(int fd = -1);\n> +       explicit FileDescriptor(const int &fd = -1);\n> +       explicit FileDescriptor(int &&fd);\n>         FileDescriptor(const FileDescriptor &other);\n>         FileDescriptor(FileDescriptor &&other);\n>         ~FileDescriptor();\n> @@ -30,7 +31,7 @@ private:\n>         class Descriptor\n>         {\n>         public:\n> -               Descriptor(int fd);\n> +               Descriptor(int fd, bool duplicate);\n>                 ~Descriptor();\n>\n>                 int fd() const { return fd_; }\n> diff --git a/src/libcamera/file_descriptor.cpp b/src/libcamera/file_descriptor.cpp\n> index ee60064bce6e..640e66e6d168 100644\n> --- a/src/libcamera/file_descriptor.cpp\n> +++ b/src/libcamera/file_descriptor.cpp\n> @@ -33,43 +33,81 @@ LOG_DEFINE_CATEGORY(FileDescriptor)\n>   * shared with all FileDescriptor instances constructed as copies.\n>   *\n>   * When constructed from a numerical file descriptor, the FileDescriptor\n> - * instance duplicates the file descriptor and wraps the duplicate as a\n> - * Descriptor. The copy constructor and assignment operator create copies that\n> - * share the Descriptor, while the move versions of those methods additionally\n> - * make the other FileDescriptor invalid. When the last FileDescriptor that\n> - * references a Descriptor is destroyed, the file descriptor is closed.\n> - *\n> - * The numerical file descriptor is available through the fd() method. As\n> - * constructing a FileDescriptor from a numerical file descriptor duplicates\n> - * the file descriptor, the value returned by fd() will be different than the\n> - * value passed to the constructor. All FileDescriptor instances created as\n> - * copies of a FileDescriptor will report the same fd() value. Callers can\n> - * perform operations on the fd(), but shall never close it manually.\n> + * instance either duplicates or takes over the file descriptor:\n> + *\n> + * - The FileDescriptor(const int &) constructor duplicates the numerical file\n> + *   descriptor and wraps the duplicate in a Descriptor. The caller is\n> + *   responsible for closing the original file descriptor, and the value\n> + *   returned by fd() will be different from the value passed to the\n> + *   constructor.\n> + *\n> + * - The FileDescriptor(int &&) constructor takes over the numerical file\n> + *   descriptor and wraps it in a Descriptor. The caller is shall not touch the\n> + *   original file descriptor once the function returns, and the value returned\n> + *   by fd() will be identical to the value passed to the constructor.\n> + *\n> + * The copy constructor and assignment operator create copies that share the\n> + * Descriptor, while the move versions of those methods additionally make the\n> + * other FileDescriptor invalid. When the last FileDescriptor that references a\n> + * Descriptor is destroyed, the file descriptor is closed.\n> + *\n> + * The numerical file descriptor is available through the fd() method. All\n> + * FileDescriptor instances created as copies of a FileDescriptor will report\n> + * the same fd() value. Callers can perform operations on the fd(), but shall\n> + * never close it manually.\n>   */\n>\n>  /**\n> - * \\brief Create a FileDescriptor wrapping a copy of a given \\a fd\n> + * \\brief Create a FileDescriptor copying a given \\a fd\n>   * \\param[in] fd File descriptor\n>   *\n> - * Constructing a FileDescriptor from a numerical file descriptor duplicates the\n> - * \\a fd and takes ownership of the copy. The original \\a fd is left untouched,\n> - * and the caller is responsible for closing it when appropriate. The duplicated\n> - * file descriptor will be closed automatically when all FileDescriptor\n> - * instances that reference it are destroyed.\n> + * Construct a FileDescriptor from a numerical file descriptor by duplicating\n> + * the \\a fd, and take ownership of the copy. The original \\a fd is left\n> + * untouched, and the caller is responsible for closing it when appropriate.\n> + * The duplicated file descriptor will be closed automatically when all\n> + * FileDescriptor instances that reference it are destroyed.\n>   *\n>   * If the \\a fd is negative, the FileDescriptor is constructed as invalid and\n>   * the fd() method will return -1.\n>   */\n> -FileDescriptor::FileDescriptor(int fd)\n> +FileDescriptor::FileDescriptor(const int &fd)\n>  {\n>         if (fd < 0)\n>                 return;\n>\n> -       fd_ = std::make_shared<Descriptor>(fd);\n> +       fd_ = std::make_shared<Descriptor>(fd, true);\n>         if (fd_->fd() < 0)\n>                 fd_.reset();\n>  }\n>\n> +/**\n> + * \\brief Create a FileDescriptor taking ownership of a given \\a fd\n> + * \\param[in] fd File descriptor\n> + *\n> + * Construct a FileDescriptor from a numerical file descriptor by taking\n> + * ownership of the \\a fd. The original \\a fd is set to -1 and shall not be\n> + * touched by the caller anymore. In particular, the caller shall not close the\n> + * original \\a fd manually. The duplicated file descriptor will be closed\n> + * automatically when all FileDescriptor instances that reference it are\n> + * destroyed.\n> + *\n> + * If the \\a fd is negative, the FileDescriptor is constructed as invalid and\n> + * the fd() method will return -1.\n> + */\n> +FileDescriptor::FileDescriptor(int &&fd)\n> +{\n> +       if (fd < 0)\n> +               return;\n> +\n> +       fd_ = std::make_shared<Descriptor>(fd, false);\n> +       /*\n> +        * The Descriptor constructor can't have failed here, as it took over\n> +        * the fd without duplicating it. Just set the original fd to -1 to\n> +        * implement move semantics.\n> +        */\n> +       fd = -1;\n> +}\n> +\n>  /**\n>   * \\brief Copy constructor, create a FileDescriptor from a copy of \\a other\n>   * \\param[in] other The other FileDescriptor\n> @@ -183,8 +221,13 @@ FileDescriptor FileDescriptor::dup() const\n>         return FileDescriptor(fd());\n>  }\n>\n> -FileDescriptor::Descriptor::Descriptor(int fd)\n> +FileDescriptor::Descriptor::Descriptor(int fd, bool duplicate)\n>  {\n> +       if (!duplicate) {\n> +               fd_ = fd;\n> +               return;\n> +       }\n> +\n>         /* Failing to dup() a fd should not happen and is fatal. */\n>         fd_ = ::dup(fd);\n>         if (fd_ == -1) {\n> --\n> Regards,\n>\n> Laurent Pinchart\n>","headers":{"Return-Path":"<naush@raspberrypi.com>","Received":["from mail-lj1-x242.google.com (mail-lj1-x242.google.com\n\t[IPv6:2a00:1450:4864:20::242])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 2CA39603D9\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 19 May 2020 16:41:01 +0200 (CEST)","by mail-lj1-x242.google.com with SMTP id b6so22264ljj.1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 19 May 2020 07:41:01 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected) header.d=raspberrypi.com\n\theader.i=@raspberrypi.com\n\theader.b=\"RbDtq8eB\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=GIV5Ylfs0Hz4NlVd4V0xdt2437Cnsq+wFDElwtpx/YM=;\n\tb=RbDtq8eBr1ejqW/qstLzOaHSstM1KNb5/B6+zjUS8gVNpH36zpFjAYA2Oa6F/ouXn/\n\tc+6CCLjAMZWmlGW+oDskOF2OYIWU5LIhvoaWqP/7A9R+o+LzhV91kRcCB9YyKE03+5ju\n\toWRC6C/j71tYqFyUr47e1mo58Zv2RDXH8VpkRitYOt8gI4soUPjE7tfYol5VRbA2x9Q3\n\tJZsnWcbOiw+r8rEssrQqXktXMqLVrEhFkxbENBWjKXybrkiI2JAOQMLCH4R9u5jDUwr9\n\tNPlyK2eLWgv6Ytaubx5uqSwcKth/kOiLsiCbwF1v+OmM+U2etf2v8+/VFYeBbtW6Vcv4\n\tK9/w==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=GIV5Ylfs0Hz4NlVd4V0xdt2437Cnsq+wFDElwtpx/YM=;\n\tb=lgtPaHzvQ6DgHYVBrq0w5n/NMIJNYlnoRC/5WYtRmHI2uEqVlRbqDlPQ6OjuGOaYFJ\n\tWqvptUarNgi9Er5KKPh8cOTsXKUinWVg5pv8yTP5n2a5HI9lsb4sAjiuGsCHNZfZxe4c\n\tBu8lo2pZbERQ1vsehNMKgfRShmGCk0R417auGBDi+xRKo3Kp6Fl4qmG+d70n7lrTs3a6\n\tVp98Tm5YukMU8tBmwUVKHmsvAAJ7LWDWRSBHjqmaBTfL52wWfPk2Gb2ChuesxJTUopN4\n\t/GSPdVguc6byINEo9Kq4ctnlVQ7ElqFH3Ax1oBNwKPZlcsaeM8NSDWFsV9v8ewJ3xkCb\n\t1c/w==","X-Gm-Message-State":"AOAM532JBfgYTIignwy39UNVNNaeTAiRC+oRkzEtO3K6QxovUemoRtqH\n\tTNblrrxC3m8SYdRSyADN5LIYhCKP8o0klyAMFt3ojA==","X-Google-Smtp-Source":"ABdhPJxYJG/DbdkCQ+f+Er95N/jg4Io+Inf2WPZQL5I/tT+kQ7Kvw3qAU8NRoo9Bneus103UtijryNObNGXFD6iejxk=","X-Received":"by 2002:a2e:884d:: with SMTP id\n\tz13mr13189590ljj.84.1589899260439; \n\tTue, 19 May 2020 07:41:00 -0700 (PDT)","MIME-Version":"1.0","References":"<20200518164804.10088-1-laurent.pinchart@ideasonboard.com>","In-Reply-To":"<20200518164804.10088-1-laurent.pinchart@ideasonboard.com>","From":"Naushir Patuck <naush@raspberrypi.com>","Date":"Tue, 19 May 2020 15:40:44 +0100","Message-ID":"<CAEmqJPriMXMET2UW0Q0EXfaA=9hYLZr2-_nfHyTGfRPn-wfU=Q@mail.gmail.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"UTF-8\"","Subject":"Re: [libcamera-devel] [PATCH 1/3] libcamera: file_descriptor:\n\tImplement move semantics for constructor","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":"Tue, 19 May 2020 14:41:01 -0000"}}]