[{"id":21321,"web_url":"https://patchwork.libcamera.org/comment/21321/","msgid":"<CAO5uPHPjrZYR8r5JjL7rThipsDb+E+ouc3P4+C83z9y7w0XgTg@mail.gmail.com>","date":"2021-11-29T13:56:34","subject":"Re: [libcamera-devel] [PATCH v3 10/17] libcamera: ipc_unixsocket:\n\tUse UniqueFD for a file descriptor","submitter":{"id":63,"url":"https://patchwork.libcamera.org/api/people/63/","name":"Hirokazu Honda","email":"hiroh@chromium.org"},"content":"Hi Laurent,\n\nOn Mon, Nov 29, 2021 at 8:58 AM Laurent Pinchart\n<laurent.pinchart@ideasonboard.com> wrote:\n>\n> From: Hirokazu Honda <hiroh@chromium.org>\n>\n> IPCUnixSocket::create() creates two file descriptors. One of\n> them is stored in IPCUnixSocket and the other is returned to a\n> caller. This clarifies the ownership using UniqueFD.\n>\n> Signed-off-by: Hirokazu Honda <hiroh@chromium.org>\n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nLooks good to me.\nReviewed-by: Hirokazu Honda <hiroh@chromium.org> if applicable.\n> ---\n> Changes since v2:\n>\n> - Pass UniqueFD to IPCUnixSocket::bind()\n> - Return {}\n> ---\n>  include/libcamera/internal/ipc_unixsocket.h   |  7 +--\n>  src/libcamera/ipc_pipe_unixsocket.cpp         |  8 ++--\n>  src/libcamera/ipc_unixsocket.cpp              | 43 ++++++++++---------\n>  test/ipc/unixsocket.cpp                       | 14 +++---\n>  test/ipc/unixsocket_ipc.cpp                   |  8 ++--\n>  .../module_ipa_proxy_worker.cpp.tmpl          | 13 +++---\n>  6 files changed, 49 insertions(+), 44 deletions(-)\n>\n> diff --git a/include/libcamera/internal/ipc_unixsocket.h b/include/libcamera/internal/ipc_unixsocket.h\n> index 5010b66a2bda..3963d182ffa6 100644\n> --- a/include/libcamera/internal/ipc_unixsocket.h\n> +++ b/include/libcamera/internal/ipc_unixsocket.h\n> @@ -12,6 +12,7 @@\n>  #include <vector>\n>\n>  #include <libcamera/base/signal.h>\n> +#include <libcamera/base/unique_fd.h>\n>\n>  namespace libcamera {\n>\n> @@ -28,8 +29,8 @@ public:\n>         IPCUnixSocket();\n>         ~IPCUnixSocket();\n>\n> -       int create();\n> -       int bind(int fd);\n> +       UniqueFD create();\n> +       int bind(UniqueFD fd);\n>         void close();\n>         bool isBound() const;\n>\n> @@ -49,7 +50,7 @@ private:\n>\n>         void dataNotifier();\n>\n> -       int fd_;\n> +       UniqueFD fd_;\n>         bool headerReceived_;\n>         struct Header header_;\n>         EventNotifier *notifier_;\n> diff --git a/src/libcamera/ipc_pipe_unixsocket.cpp b/src/libcamera/ipc_pipe_unixsocket.cpp\n> index 533560cf95d3..65277500ff42 100644\n> --- a/src/libcamera/ipc_pipe_unixsocket.cpp\n> +++ b/src/libcamera/ipc_pipe_unixsocket.cpp\n> @@ -31,14 +31,14 @@ IPCPipeUnixSocket::IPCPipeUnixSocket(const char *ipaModulePath,\n>         args.push_back(ipaModulePath);\n>\n>         socket_ = std::make_unique<IPCUnixSocket>();\n> -       int fd = socket_->create();\n> -       if (fd < 0) {\n> +       UniqueFD fd = socket_->create();\n> +       if (!fd.isValid()) {\n>                 LOG(IPCPipe, Error) << \"Failed to create socket\";\n>                 return;\n>         }\n>         socket_->readyRead.connect(this, &IPCPipeUnixSocket::readyRead);\n> -       args.push_back(std::to_string(fd));\n> -       fds.push_back(fd);\n> +       args.push_back(std::to_string(fd.get()));\n> +       fds.push_back(fd.release());\n>\n>         proc_ = std::make_unique<Process>();\n>         int ret = proc_->start(ipaProxyWorkerPath, args, fds);\n> diff --git a/src/libcamera/ipc_unixsocket.cpp b/src/libcamera/ipc_unixsocket.cpp\n> index bd32fca3a678..1980d374cea8 100644\n> --- a/src/libcamera/ipc_unixsocket.cpp\n> +++ b/src/libcamera/ipc_unixsocket.cpp\n> @@ -7,6 +7,7 @@\n>\n>  #include \"libcamera/internal/ipc_unixsocket.h\"\n>\n> +#include <array>\n>  #include <poll.h>\n>  #include <string.h>\n>  #include <sys/socket.h>\n> @@ -68,7 +69,7 @@ LOG_DEFINE_CATEGORY(IPCUnixSocket)\n>   */\n>\n>  IPCUnixSocket::IPCUnixSocket()\n> -       : fd_(-1), headerReceived_(false), notifier_(nullptr)\n> +       : headerReceived_(false), notifier_(nullptr)\n>  {\n>  }\n>\n> @@ -86,9 +87,9 @@ IPCUnixSocket::~IPCUnixSocket()\n>   * to the remote process, where it can be used with IPCUnixSocket::bind() to\n>   * bind the remote side socket.\n>   *\n> - * \\return A file descriptor on success, negative error code on failure\n> + * \\return A file descriptor. It is valid on success or invalid otherwise.\n>   */\n> -int IPCUnixSocket::create()\n> +UniqueFD IPCUnixSocket::create()\n>  {\n>         int sockets[2];\n>         int ret;\n> @@ -98,14 +99,18 @@ int IPCUnixSocket::create()\n>                 ret = -errno;\n>                 LOG(IPCUnixSocket, Error)\n>                         << \"Failed to create socket pair: \" << strerror(-ret);\n> -               return ret;\n> +               return {};\n>         }\n>\n> -       ret = bind(sockets[0]);\n> -       if (ret)\n> -               return ret;\n> +       std::array<UniqueFD, 2> socketFds{\n> +               UniqueFD(sockets[0]),\n> +               UniqueFD(sockets[1]),\n> +       };\n>\n> -       return sockets[1];\n> +       if (bind(std::move(socketFds[0])) < 0)\n> +               return {};\n> +\n> +       return std::move(socketFds[1]);\n>  }\n>\n>  /**\n> @@ -118,13 +123,13 @@ int IPCUnixSocket::create()\n>   *\n>   * \\return 0 on success or a negative error code otherwise\n>   */\n> -int IPCUnixSocket::bind(int fd)\n> +int IPCUnixSocket::bind(UniqueFD fd)\n>  {\n>         if (isBound())\n>                 return -EINVAL;\n>\n> -       fd_ = fd;\n> -       notifier_ = new EventNotifier(fd_, EventNotifier::Read);\n> +       fd_ = std::move(fd);\n> +       notifier_ = new EventNotifier(fd_.get(), EventNotifier::Read);\n>         notifier_->activated.connect(this, &IPCUnixSocket::dataNotifier);\n>\n>         return 0;\n> @@ -143,9 +148,7 @@ void IPCUnixSocket::close()\n>         delete notifier_;\n>         notifier_ = nullptr;\n>\n> -       ::close(fd_);\n> -\n> -       fd_ = -1;\n> +       fd_.reset();\n>         headerReceived_ = false;\n>  }\n>\n> @@ -155,7 +158,7 @@ void IPCUnixSocket::close()\n>   */\n>  bool IPCUnixSocket::isBound() const\n>  {\n> -       return fd_ != -1;\n> +       return fd_.isValid();\n>  }\n>\n>  /**\n> @@ -182,7 +185,7 @@ int IPCUnixSocket::send(const Payload &payload)\n>         if (!hdr.data && !hdr.fds)\n>                 return -EINVAL;\n>\n> -       ret = ::send(fd_, &hdr, sizeof(hdr), 0);\n> +       ret = ::send(fd_.get(), &hdr, sizeof(hdr), 0);\n>         if (ret < 0) {\n>                 ret = -errno;\n>                 LOG(IPCUnixSocket, Error)\n> @@ -263,7 +266,7 @@ int IPCUnixSocket::sendData(const void *buffer, size_t length,\n>         if (fds)\n>                 memcpy(CMSG_DATA(cmsg), fds, num * sizeof(uint32_t));\n>\n> -       if (sendmsg(fd_, &msg, 0) < 0) {\n> +       if (sendmsg(fd_.get(), &msg, 0) < 0) {\n>                 int ret = -errno;\n>                 LOG(IPCUnixSocket, Error)\n>                         << \"Failed to sendmsg: \" << strerror(-ret);\n> @@ -297,7 +300,7 @@ int IPCUnixSocket::recvData(void *buffer, size_t length,\n>         msg.msg_controllen = cmsg->cmsg_len;\n>         msg.msg_flags = 0;\n>\n> -       if (recvmsg(fd_, &msg, 0) < 0) {\n> +       if (recvmsg(fd_.get(), &msg, 0) < 0) {\n>                 int ret = -errno;\n>                 if (ret != -EAGAIN)\n>                         LOG(IPCUnixSocket, Error)\n> @@ -317,7 +320,7 @@ void IPCUnixSocket::dataNotifier()\n>\n>         if (!headerReceived_) {\n>                 /* Receive the header. */\n> -               ret = ::recv(fd_, &header_, sizeof(header_), 0);\n> +               ret = ::recv(fd_.get(), &header_, sizeof(header_), 0);\n>                 if (ret < 0) {\n>                         ret = -errno;\n>                         LOG(IPCUnixSocket, Error)\n> @@ -333,7 +336,7 @@ void IPCUnixSocket::dataNotifier()\n>          * readyRead signal. The notifier will be reenabled by the receive()\n>          * function.\n>          */\n> -       struct pollfd fds = { fd_, POLLIN, 0 };\n> +       struct pollfd fds = { fd_.get(), POLLIN, 0 };\n>         ret = poll(&fds, 1, 0);\n>         if (ret < 0)\n>                 return;\n> diff --git a/test/ipc/unixsocket.cpp b/test/ipc/unixsocket.cpp\n> index 7270bf4d2fe7..414f1bfc9d12 100644\n> --- a/test/ipc/unixsocket.cpp\n> +++ b/test/ipc/unixsocket.cpp\n> @@ -52,9 +52,9 @@ public:\n>                 ipc_.readyRead.connect(this, &UnixSocketTestSlave::readyRead);\n>         }\n>\n> -       int run(int fd)\n> +       int run(UniqueFD fd)\n>         {\n> -               if (ipc_.bind(fd)) {\n> +               if (ipc_.bind(std::move(fd))) {\n>                         cerr << \"Failed to connect to IPC channel\" << endl;\n>                         return EXIT_FAILURE;\n>                 }\n> @@ -360,11 +360,11 @@ protected:\n>\n>         int run()\n>         {\n> -               int slavefd = ipc_.create();\n> -               if (slavefd < 0)\n> +               UniqueFD slavefd = ipc_.create();\n> +               if (!slavefd.isValid())\n>                         return TestFail;\n>\n> -               if (slaveStart(slavefd)) {\n> +               if (slaveStart(slavefd.release())) {\n>                         cerr << \"Failed to start slave\" << endl;\n>                         return TestFail;\n>                 }\n> @@ -496,9 +496,9 @@ private:\n>  int main(int argc, char **argv)\n>  {\n>         if (argc == 2) {\n> -               int ipcfd = std::stoi(argv[1]);\n> +               UniqueFD ipcfd = UniqueFD(std::stoi(argv[1]));\n>                 UnixSocketTestSlave slave;\n> -               return slave.run(ipcfd);\n> +               return slave.run(std::move(ipcfd));\n>         }\n>\n>         return UnixSocketTest().execute();\n> diff --git a/test/ipc/unixsocket_ipc.cpp b/test/ipc/unixsocket_ipc.cpp\n> index ab5d25572d83..178ee1870056 100644\n> --- a/test/ipc/unixsocket_ipc.cpp\n> +++ b/test/ipc/unixsocket_ipc.cpp\n> @@ -49,9 +49,9 @@ public:\n>                 ipc_.readyRead.connect(this, &UnixSocketTestIPCSlave::readyRead);\n>         }\n>\n> -       int run(int fd)\n> +       int run(UniqueFD fd)\n>         {\n> -               if (ipc_.bind(fd)) {\n> +               if (ipc_.bind(std::move(fd))) {\n>                         cerr << \"Failed to connect to IPC channel\" << endl;\n>                         return EXIT_FAILURE;\n>                 }\n> @@ -222,9 +222,9 @@ int main(int argc, char **argv)\n>  {\n>         /* IPCPipeUnixSocket passes IPA module path in argv[1] */\n>         if (argc == 3) {\n> -               int ipcfd = std::stoi(argv[2]);\n> +               UniqueFD ipcfd = UniqueFD(std::stoi(argv[2]));\n>                 UnixSocketTestIPCSlave slave;\n> -               return slave.run(ipcfd);\n> +               return slave.run(std::move(ipcfd));\n>         }\n>\n>         return UnixSocketTestIPC().execute();\n> diff --git a/utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl b/utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl\n> index 764e7a3af63a..b65dc4cf31c5 100644\n> --- a/utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl\n> +++ b/utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl\n> @@ -27,8 +27,9 @@\n>  #include <libcamera/logging.h>\n>\n>  #include <libcamera/base/event_dispatcher.h>\n> -#include <libcamera/base/thread.h>\n>  #include <libcamera/base/log.h>\n> +#include <libcamera/base/thread.h>\n> +#include <libcamera/base/unique_fd.h>\n>\n>  #include \"libcamera/internal/camera_sensor.h\"\n>  #include \"libcamera/internal/control_serializer.h\"\n> @@ -122,9 +123,9 @@ public:\n>                 }\n>         }\n>\n> -       int init(std::unique_ptr<IPAModule> &ipam, int socketfd)\n> +       int init(std::unique_ptr<IPAModule> &ipam, UniqueFD socketfd)\n>         {\n> -               if (socket_.bind(socketfd) < 0) {\n> +               if (socket_.bind(std::move(socketfd)) < 0) {\n>                         LOG({{proxy_worker_name}}, Error)\n>                                 << \"IPC socket binding failed\";\n>                         return EXIT_FAILURE;\n> @@ -203,10 +204,10 @@ int main(int argc, char **argv)\n>                 return EXIT_FAILURE;\n>         }\n>\n> -       int fd = std::stoi(argv[2]);\n> +       UniqueFD fd(std::stoi(argv[2]));\n>         LOG({{proxy_worker_name}}, Info)\n>                 << \"Starting worker for IPA module \" << argv[1]\n> -               << \" with IPC fd = \" << fd;\n> +               << \" with IPC fd = \" << fd.get();\n>\n>         std::unique_ptr<IPAModule> ipam = std::make_unique<IPAModule>(argv[1]);\n>         if (!ipam->isValid() || !ipam->load()) {\n> @@ -228,7 +229,7 @@ int main(int argc, char **argv)\n>         }\n>\n>         {{proxy_worker_name}} proxyWorker;\n> -       int ret = proxyWorker.init(ipam, fd);\n> +       int ret = proxyWorker.init(ipam, std::move(fd));\n>         if (ret < 0) {\n>                 LOG({{proxy_worker_name}}, Error)\n>                         << \"Failed to initialize proxy worker\";\n> --\n> Regards,\n>\n> Laurent Pinchart\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 2DD31BF415\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 29 Nov 2021 13:56:49 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 893C4605A4;\n\tMon, 29 Nov 2021 14:56:48 +0100 (CET)","from mail-ed1-x531.google.com (mail-ed1-x531.google.com\n\t[IPv6:2a00:1450:4864:20::531])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 08A6760592\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 29 Nov 2021 14:56:47 +0100 (CET)","by mail-ed1-x531.google.com with SMTP id x15so72184816edv.1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 29 Nov 2021 05:56:46 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=chromium.org header.i=@chromium.org\n\theader.b=\"iL0YPwmX\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org;\n\ts=google; \n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=kTDxYoe6uWR8jn+oRmQFmsAVhF3kvCUerxWn+srb6HE=;\n\tb=iL0YPwmXRbS2ihTRMg33M5fSPHCmu6CoJ1g3TtHJfJsTA/uw+IruM7YFa7tzymGs8x\n\tSWpcEZmxCpyD8bUhBboJ3TNkSvAp8DE7DBfl34O54aXfccSGW7yF/2Y052k9iNGlfmic\n\tArQU8gvFhuws8BqlPpfkaiWTMzFeORqN74j5U=","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=kTDxYoe6uWR8jn+oRmQFmsAVhF3kvCUerxWn+srb6HE=;\n\tb=RO70mRz+89YsmII1zL50cblgh2AqJr3OFvMvqVkmiSpovTRHyDwKMwBPi/dEriEM5p\n\tk45VKfMTjhiLRD9BFyv1wHMvjEayyOMee+ktjZMut0ydwMyV2BiudoVtsEHej81CUqDv\n\tOjhFI5Lb6RdLDnmuSVpxfbUd8lWVe1g5Fw1rBRpwHNe2T7fJSjNY37bPlecxxza5hQz/\n\t3EZY1wlHPsWTKc0BVI4k8A24HBKF42lYeYjsM1V2Hq61VJ3uhITWSQkjpU09hJnf8Ws3\n\trLhBKT0hSi/uNbWlq7io9m1WrclstxWVr5FrQ37VjIJRqCGz57rUfrA65NRN+ZM4ZJ6S\n\t+t9w==","X-Gm-Message-State":"AOAM530zNfH7HvArFZbs0OzZqBxc9/yeRCEUMRUX0X+dDqV83xbU7rp7\n\t3Luh7eUbDmImH5gbEoya5I06f9vw6SOP59EqL5oxt+/YQu0=","X-Google-Smtp-Source":"ABdhPJytnoGyHdrAQvbY3FZ0xRHR5lBW2xZdaISLV+fXfha28ag4PVnUrVeyvPYsYJUEvZ2aWO+j+5e5SfeP5KMh/fE=","X-Received":"by 2002:a17:906:7310:: with SMTP id\n\tdi16mr58385534ejc.92.1638194206443; \n\tMon, 29 Nov 2021 05:56:46 -0800 (PST)","MIME-Version":"1.0","References":"<20211128235752.10836-1-laurent.pinchart@ideasonboard.com>\n\t<20211128235752.10836-11-laurent.pinchart@ideasonboard.com>","In-Reply-To":"<20211128235752.10836-11-laurent.pinchart@ideasonboard.com>","From":"Hirokazu Honda <hiroh@chromium.org>","Date":"Mon, 29 Nov 2021 22:56:34 +0900","Message-ID":"<CAO5uPHPjrZYR8r5JjL7rThipsDb+E+ouc3P4+C83z9y7w0XgTg@mail.gmail.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Content-Type":"text/plain; charset=\"UTF-8\"","Subject":"Re: [libcamera-devel] [PATCH v3 10/17] libcamera: ipc_unixsocket:\n\tUse UniqueFD for a file descriptor","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>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":21339,"web_url":"https://patchwork.libcamera.org/comment/21339/","msgid":"<20211129153351.6r7m6qahvqcb2bcr@uno.localdomain>","date":"2021-11-29T15:33:51","subject":"Re: [libcamera-devel] [PATCH v3 10/17] libcamera: ipc_unixsocket:\n\tUse UniqueFD for a file descriptor","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"On Mon, Nov 29, 2021 at 01:57:45AM +0200, Laurent Pinchart wrote:\n> From: Hirokazu Honda <hiroh@chromium.org>\n>\n> IPCUnixSocket::create() creates two file descriptors. One of\n> them is stored in IPCUnixSocket and the other is returned to a\n> caller. This clarifies the ownership using UniqueFD.\n>\n> Signed-off-by: Hirokazu Honda <hiroh@chromium.org>\n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> ---\n> Changes since v2:\n>\n> - Pass UniqueFD to IPCUnixSocket::bind()\n> - Return {}\n> ---\n>  include/libcamera/internal/ipc_unixsocket.h   |  7 +--\n>  src/libcamera/ipc_pipe_unixsocket.cpp         |  8 ++--\n>  src/libcamera/ipc_unixsocket.cpp              | 43 ++++++++++---------\n>  test/ipc/unixsocket.cpp                       | 14 +++---\n>  test/ipc/unixsocket_ipc.cpp                   |  8 ++--\n>  .../module_ipa_proxy_worker.cpp.tmpl          | 13 +++---\n>  6 files changed, 49 insertions(+), 44 deletions(-)\n>\n> diff --git a/include/libcamera/internal/ipc_unixsocket.h b/include/libcamera/internal/ipc_unixsocket.h\n> index 5010b66a2bda..3963d182ffa6 100644\n> --- a/include/libcamera/internal/ipc_unixsocket.h\n> +++ b/include/libcamera/internal/ipc_unixsocket.h\n> @@ -12,6 +12,7 @@\n>  #include <vector>\n>\n>  #include <libcamera/base/signal.h>\n> +#include <libcamera/base/unique_fd.h>\n>\n>  namespace libcamera {\n>\n> @@ -28,8 +29,8 @@ public:\n>  \tIPCUnixSocket();\n>  \t~IPCUnixSocket();\n>\n> -\tint create();\n> -\tint bind(int fd);\n> +\tUniqueFD create();\n> +\tint bind(UniqueFD fd);\n>  \tvoid close();\n>  \tbool isBound() const;\n>\n> @@ -49,7 +50,7 @@ private:\n>\n>  \tvoid dataNotifier();\n>\n> -\tint fd_;\n> +\tUniqueFD fd_;\n>  \tbool headerReceived_;\n>  \tstruct Header header_;\n>  \tEventNotifier *notifier_;\n> diff --git a/src/libcamera/ipc_pipe_unixsocket.cpp b/src/libcamera/ipc_pipe_unixsocket.cpp\n> index 533560cf95d3..65277500ff42 100644\n> --- a/src/libcamera/ipc_pipe_unixsocket.cpp\n> +++ b/src/libcamera/ipc_pipe_unixsocket.cpp\n> @@ -31,14 +31,14 @@ IPCPipeUnixSocket::IPCPipeUnixSocket(const char *ipaModulePath,\n>  \targs.push_back(ipaModulePath);\n>\n>  \tsocket_ = std::make_unique<IPCUnixSocket>();\n> -\tint fd = socket_->create();\n> -\tif (fd < 0) {\n> +\tUniqueFD fd = socket_->create();\n> +\tif (!fd.isValid()) {\n>  \t\tLOG(IPCPipe, Error) << \"Failed to create socket\";\n>  \t\treturn;\n>  \t}\n>  \tsocket_->readyRead.connect(this, &IPCPipeUnixSocket::readyRead);\n> -\targs.push_back(std::to_string(fd));\n> -\tfds.push_back(fd);\n\nWas in the previous version fd leaked ??\n\n> +\targs.push_back(std::to_string(fd.get()));\n> +\tfds.push_back(fd.release());\n>\n>  \tproc_ = std::make_unique<Process>();\n>  \tint ret = proc_->start(ipaProxyWorkerPath, args, fds);\n> diff --git a/src/libcamera/ipc_unixsocket.cpp b/src/libcamera/ipc_unixsocket.cpp\n> index bd32fca3a678..1980d374cea8 100644\n> --- a/src/libcamera/ipc_unixsocket.cpp\n> +++ b/src/libcamera/ipc_unixsocket.cpp\n> @@ -7,6 +7,7 @@\n>\n>  #include \"libcamera/internal/ipc_unixsocket.h\"\n>\n> +#include <array>\n>  #include <poll.h>\n>  #include <string.h>\n>  #include <sys/socket.h>\n> @@ -68,7 +69,7 @@ LOG_DEFINE_CATEGORY(IPCUnixSocket)\n>   */\n>\n>  IPCUnixSocket::IPCUnixSocket()\n> -\t: fd_(-1), headerReceived_(false), notifier_(nullptr)\n> +\t: headerReceived_(false), notifier_(nullptr)\n>  {\n>  }\n>\n> @@ -86,9 +87,9 @@ IPCUnixSocket::~IPCUnixSocket()\n>   * to the remote process, where it can be used with IPCUnixSocket::bind() to\n>   * bind the remote side socket.\n>   *\n> - * \\return A file descriptor on success, negative error code on failure\n> + * \\return A file descriptor. It is valid on success or invalid otherwise.\n>   */\n> -int IPCUnixSocket::create()\n> +UniqueFD IPCUnixSocket::create()\n>  {\n>  \tint sockets[2];\n>  \tint ret;\n> @@ -98,14 +99,18 @@ int IPCUnixSocket::create()\n>  \t\tret = -errno;\n>  \t\tLOG(IPCUnixSocket, Error)\n>  \t\t\t<< \"Failed to create socket pair: \" << strerror(-ret);\n> -\t\treturn ret;\n> +\t\treturn {};\n>  \t}\n>\n> -\tret = bind(sockets[0]);\n> -\tif (ret)\n> -\t\treturn ret;\n> +\tstd::array<UniqueFD, 2> socketFds{\n> +\t\tUniqueFD(sockets[0]),\n> +\t\tUniqueFD(sockets[1]),\n> +\t};\n>\n> -\treturn sockets[1];\n> +\tif (bind(std::move(socketFds[0])) < 0)\n> +\t\treturn {};\n> +\n> +\treturn std::move(socketFds[1]);\n>  }\n>\n>  /**\n> @@ -118,13 +123,13 @@ int IPCUnixSocket::create()\n>   *\n>   * \\return 0 on success or a negative error code otherwise\n>   */\n> -int IPCUnixSocket::bind(int fd)\n> +int IPCUnixSocket::bind(UniqueFD fd)\n>  {\n>  \tif (isBound())\n>  \t\treturn -EINVAL;\n>\n> -\tfd_ = fd;\n> -\tnotifier_ = new EventNotifier(fd_, EventNotifier::Read);\n> +\tfd_ = std::move(fd);\n> +\tnotifier_ = new EventNotifier(fd_.get(), EventNotifier::Read);\n>  \tnotifier_->activated.connect(this, &IPCUnixSocket::dataNotifier);\n>\n>  \treturn 0;\n> @@ -143,9 +148,7 @@ void IPCUnixSocket::close()\n>  \tdelete notifier_;\n>  \tnotifier_ = nullptr;\n>\n> -\t::close(fd_);\n> -\n> -\tfd_ = -1;\n> +\tfd_.reset();\n>  \theaderReceived_ = false;\n>  }\n>\n> @@ -155,7 +158,7 @@ void IPCUnixSocket::close()\n>   */\n>  bool IPCUnixSocket::isBound() const\n>  {\n> -\treturn fd_ != -1;\n> +\treturn fd_.isValid();\n>  }\n>\n>  /**\n> @@ -182,7 +185,7 @@ int IPCUnixSocket::send(const Payload &payload)\n>  \tif (!hdr.data && !hdr.fds)\n>  \t\treturn -EINVAL;\n>\n> -\tret = ::send(fd_, &hdr, sizeof(hdr), 0);\n> +\tret = ::send(fd_.get(), &hdr, sizeof(hdr), 0);\n>  \tif (ret < 0) {\n>  \t\tret = -errno;\n>  \t\tLOG(IPCUnixSocket, Error)\n> @@ -263,7 +266,7 @@ int IPCUnixSocket::sendData(const void *buffer, size_t length,\n>  \tif (fds)\n>  \t\tmemcpy(CMSG_DATA(cmsg), fds, num * sizeof(uint32_t));\n>\n> -\tif (sendmsg(fd_, &msg, 0) < 0) {\n> +\tif (sendmsg(fd_.get(), &msg, 0) < 0) {\n>  \t\tint ret = -errno;\n>  \t\tLOG(IPCUnixSocket, Error)\n>  \t\t\t<< \"Failed to sendmsg: \" << strerror(-ret);\n> @@ -297,7 +300,7 @@ int IPCUnixSocket::recvData(void *buffer, size_t length,\n>  \tmsg.msg_controllen = cmsg->cmsg_len;\n>  \tmsg.msg_flags = 0;\n>\n> -\tif (recvmsg(fd_, &msg, 0) < 0) {\n> +\tif (recvmsg(fd_.get(), &msg, 0) < 0) {\n>  \t\tint ret = -errno;\n>  \t\tif (ret != -EAGAIN)\n>  \t\t\tLOG(IPCUnixSocket, Error)\n> @@ -317,7 +320,7 @@ void IPCUnixSocket::dataNotifier()\n>\n>  \tif (!headerReceived_) {\n>  \t\t/* Receive the header. */\n> -\t\tret = ::recv(fd_, &header_, sizeof(header_), 0);\n> +\t\tret = ::recv(fd_.get(), &header_, sizeof(header_), 0);\n>  \t\tif (ret < 0) {\n>  \t\t\tret = -errno;\n>  \t\t\tLOG(IPCUnixSocket, Error)\n> @@ -333,7 +336,7 @@ void IPCUnixSocket::dataNotifier()\n>  \t * readyRead signal. The notifier will be reenabled by the receive()\n>  \t * function.\n>  \t */\n> -\tstruct pollfd fds = { fd_, POLLIN, 0 };\n> +\tstruct pollfd fds = { fd_.get(), POLLIN, 0 };\n>  \tret = poll(&fds, 1, 0);\n>  \tif (ret < 0)\n>  \t\treturn;\n> diff --git a/test/ipc/unixsocket.cpp b/test/ipc/unixsocket.cpp\n> index 7270bf4d2fe7..414f1bfc9d12 100644\n> --- a/test/ipc/unixsocket.cpp\n> +++ b/test/ipc/unixsocket.cpp\n> @@ -52,9 +52,9 @@ public:\n>  \t\tipc_.readyRead.connect(this, &UnixSocketTestSlave::readyRead);\n>  \t}\n>\n> -\tint run(int fd)\n> +\tint run(UniqueFD fd)\n>  \t{\n> -\t\tif (ipc_.bind(fd)) {\n> +\t\tif (ipc_.bind(std::move(fd))) {\n>  \t\t\tcerr << \"Failed to connect to IPC channel\" << endl;\n>  \t\t\treturn EXIT_FAILURE;\n>  \t\t}\n> @@ -360,11 +360,11 @@ protected:\n>\n>  \tint run()\n>  \t{\n> -\t\tint slavefd = ipc_.create();\n> -\t\tif (slavefd < 0)\n> +\t\tUniqueFD slavefd = ipc_.create();\n> +\t\tif (!slavefd.isValid())\n>  \t\t\treturn TestFail;\n>\n> -\t\tif (slaveStart(slavefd)) {\n> +\t\tif (slaveStart(slavefd.release())) {\n>  \t\t\tcerr << \"Failed to start slave\" << endl;\n>  \t\t\treturn TestFail;\n>  \t\t}\n> @@ -496,9 +496,9 @@ private:\n>  int main(int argc, char **argv)\n>  {\n>  \tif (argc == 2) {\n> -\t\tint ipcfd = std::stoi(argv[1]);\n> +\t\tUniqueFD ipcfd = UniqueFD(std::stoi(argv[1]));\n>  \t\tUnixSocketTestSlave slave;\n> -\t\treturn slave.run(ipcfd);\n> +\t\treturn slave.run(std::move(ipcfd));\n>  \t}\n>\n>  \treturn UnixSocketTest().execute();\n> diff --git a/test/ipc/unixsocket_ipc.cpp b/test/ipc/unixsocket_ipc.cpp\n> index ab5d25572d83..178ee1870056 100644\n> --- a/test/ipc/unixsocket_ipc.cpp\n> +++ b/test/ipc/unixsocket_ipc.cpp\n> @@ -49,9 +49,9 @@ public:\n>  \t\tipc_.readyRead.connect(this, &UnixSocketTestIPCSlave::readyRead);\n>  \t}\n>\n> -\tint run(int fd)\n> +\tint run(UniqueFD fd)\n>  \t{\n> -\t\tif (ipc_.bind(fd)) {\n> +\t\tif (ipc_.bind(std::move(fd))) {\n>  \t\t\tcerr << \"Failed to connect to IPC channel\" << endl;\n>  \t\t\treturn EXIT_FAILURE;\n>  \t\t}\n> @@ -222,9 +222,9 @@ int main(int argc, char **argv)\n>  {\n>  \t/* IPCPipeUnixSocket passes IPA module path in argv[1] */\n>  \tif (argc == 3) {\n> -\t\tint ipcfd = std::stoi(argv[2]);\n> +\t\tUniqueFD ipcfd = UniqueFD(std::stoi(argv[2]));\n>  \t\tUnixSocketTestIPCSlave slave;\n> -\t\treturn slave.run(ipcfd);\n> +\t\treturn slave.run(std::move(ipcfd));\n>  \t}\n>\n>  \treturn UnixSocketTestIPC().execute();\n> diff --git a/utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl b/utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl\n> index 764e7a3af63a..b65dc4cf31c5 100644\n> --- a/utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl\n> +++ b/utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl\n> @@ -27,8 +27,9 @@\n>  #include <libcamera/logging.h>\n>\n>  #include <libcamera/base/event_dispatcher.h>\n> -#include <libcamera/base/thread.h>\n>  #include <libcamera/base/log.h>\n> +#include <libcamera/base/thread.h>\n> +#include <libcamera/base/unique_fd.h>\n>\n>  #include \"libcamera/internal/camera_sensor.h\"\n>  #include \"libcamera/internal/control_serializer.h\"\n> @@ -122,9 +123,9 @@ public:\n>  \t\t}\n>  \t}\n>\n> -\tint init(std::unique_ptr<IPAModule> &ipam, int socketfd)\n> +\tint init(std::unique_ptr<IPAModule> &ipam, UniqueFD socketfd)\n>  \t{\n> -\t\tif (socket_.bind(socketfd) < 0) {\n> +\t\tif (socket_.bind(std::move(socketfd)) < 0) {\nIs this bind() IPCUnixSocket::bind(UniqueFD fd) ?\ndo you need to move then ?\n\n>  \t\t\tLOG({{proxy_worker_name}}, Error)\n>  \t\t\t\t<< \"IPC socket binding failed\";\n>  \t\t\treturn EXIT_FAILURE;\n> @@ -203,10 +204,10 @@ int main(int argc, char **argv)\n>  \t\treturn EXIT_FAILURE;\n>  \t}\n>\n> -\tint fd = std::stoi(argv[2]);\n> +\tUniqueFD fd(std::stoi(argv[2]));\n>  \tLOG({{proxy_worker_name}}, Info)\n>  \t\t<< \"Starting worker for IPA module \" << argv[1]\n> -\t\t<< \" with IPC fd = \" << fd;\n> +\t\t<< \" with IPC fd = \" << fd.get();\n>\n>  \tstd::unique_ptr<IPAModule> ipam = std::make_unique<IPAModule>(argv[1]);\n>  \tif (!ipam->isValid() || !ipam->load()) {\n> @@ -228,7 +229,7 @@ int main(int argc, char **argv)\n>  \t}\n>\n>  \t{{proxy_worker_name}} proxyWorker;\n> -\tint ret = proxyWorker.init(ipam, fd);\n> +\tint ret = proxyWorker.init(ipam, std::move(fd));\n\nSame question\n\nThanks\n  j\n>  \tif (ret < 0) {\n>  \t\tLOG({{proxy_worker_name}}, Error)\n>  \t\t\t<< \"Failed to initialize proxy worker\";\n> --\n> Regards,\n>\n> Laurent Pinchart\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id A02B6BF415\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 29 Nov 2021 15:33:01 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 53C78605A4;\n\tMon, 29 Nov 2021 16:33:01 +0100 (CET)","from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net\n\t[217.70.183.201])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 99C4260592\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 29 Nov 2021 16:32:59 +0100 (CET)","(Authenticated sender: jacopo@jmondi.org)\n\tby relay8-d.mail.gandi.net (Postfix) with ESMTPSA id 2E46A1BF215;\n\tMon, 29 Nov 2021 15:32:58 +0000 (UTC)"],"Date":"Mon, 29 Nov 2021 16:33:51 +0100","From":"Jacopo Mondi <jacopo@jmondi.org>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Message-ID":"<20211129153351.6r7m6qahvqcb2bcr@uno.localdomain>","References":"<20211128235752.10836-1-laurent.pinchart@ideasonboard.com>\n\t<20211128235752.10836-11-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20211128235752.10836-11-laurent.pinchart@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v3 10/17] libcamera: ipc_unixsocket:\n\tUse UniqueFD for a file descriptor","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>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":21346,"web_url":"https://patchwork.libcamera.org/comment/21346/","msgid":"<20211129155436.drel2ymii3phzqrp@uno.localdomain>","date":"2021-11-29T15:54:36","subject":"Re: [libcamera-devel] [PATCH v3 10/17] libcamera: ipc_unixsocket:\n\tUse UniqueFD for a file descriptor","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"Hi again\n\nOn Mon, Nov 29, 2021 at 04:33:51PM +0100, Jacopo Mondi wrote:\n> On Mon, Nov 29, 2021 at 01:57:45AM +0200, Laurent Pinchart wrote:\n> > From: Hirokazu Honda <hiroh@chromium.org>\n> >\n> > IPCUnixSocket::create() creates two file descriptors. One of\n> > them is stored in IPCUnixSocket and the other is returned to a\n> > caller. This clarifies the ownership using UniqueFD.\n> >\n> > Signed-off-by: Hirokazu Honda <hiroh@chromium.org>\n> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > ---\n> > Changes since v2:\n> >\n> > - Pass UniqueFD to IPCUnixSocket::bind()\n> > - Return {}\n> > ---\n> >  include/libcamera/internal/ipc_unixsocket.h   |  7 +--\n> >  src/libcamera/ipc_pipe_unixsocket.cpp         |  8 ++--\n> >  src/libcamera/ipc_unixsocket.cpp              | 43 ++++++++++---------\n> >  test/ipc/unixsocket.cpp                       | 14 +++---\n> >  test/ipc/unixsocket_ipc.cpp                   |  8 ++--\n> >  .../module_ipa_proxy_worker.cpp.tmpl          | 13 +++---\n> >  6 files changed, 49 insertions(+), 44 deletions(-)\n> >\n> > diff --git a/include/libcamera/internal/ipc_unixsocket.h b/include/libcamera/internal/ipc_unixsocket.h\n> > index 5010b66a2bda..3963d182ffa6 100644\n> > --- a/include/libcamera/internal/ipc_unixsocket.h\n> > +++ b/include/libcamera/internal/ipc_unixsocket.h\n> > @@ -12,6 +12,7 @@\n> >  #include <vector>\n> >\n> >  #include <libcamera/base/signal.h>\n> > +#include <libcamera/base/unique_fd.h>\n> >\n> >  namespace libcamera {\n> >\n> > @@ -28,8 +29,8 @@ public:\n> >  \tIPCUnixSocket();\n> >  \t~IPCUnixSocket();\n> >\n> > -\tint create();\n> > -\tint bind(int fd);\n> > +\tUniqueFD create();\n> > +\tint bind(UniqueFD fd);\n> >  \tvoid close();\n> >  \tbool isBound() const;\n> >\n> > @@ -49,7 +50,7 @@ private:\n> >\n> >  \tvoid dataNotifier();\n> >\n> > -\tint fd_;\n> > +\tUniqueFD fd_;\n> >  \tbool headerReceived_;\n> >  \tstruct Header header_;\n> >  \tEventNotifier *notifier_;\n> > diff --git a/src/libcamera/ipc_pipe_unixsocket.cpp b/src/libcamera/ipc_pipe_unixsocket.cpp\n> > index 533560cf95d3..65277500ff42 100644\n> > --- a/src/libcamera/ipc_pipe_unixsocket.cpp\n> > +++ b/src/libcamera/ipc_pipe_unixsocket.cpp\n> > @@ -31,14 +31,14 @@ IPCPipeUnixSocket::IPCPipeUnixSocket(const char *ipaModulePath,\n> >  \targs.push_back(ipaModulePath);\n> >\n> >  \tsocket_ = std::make_unique<IPCUnixSocket>();\n> > -\tint fd = socket_->create();\n> > -\tif (fd < 0) {\n> > +\tUniqueFD fd = socket_->create();\n> > +\tif (!fd.isValid()) {\n> >  \t\tLOG(IPCPipe, Error) << \"Failed to create socket\";\n> >  \t\treturn;\n> >  \t}\n> >  \tsocket_->readyRead.connect(this, &IPCPipeUnixSocket::readyRead);\n> > -\targs.push_back(std::to_string(fd));\n> > -\tfds.push_back(fd);\n>\n> Was in the previous version fd leaked ??\n>\n> > +\targs.push_back(std::to_string(fd.get()));\n> > +\tfds.push_back(fd.release());\n> >\n> >  \tproc_ = std::make_unique<Process>();\n> >  \tint ret = proc_->start(ipaProxyWorkerPath, args, fds);\n> > diff --git a/src/libcamera/ipc_unixsocket.cpp b/src/libcamera/ipc_unixsocket.cpp\n> > index bd32fca3a678..1980d374cea8 100644\n> > --- a/src/libcamera/ipc_unixsocket.cpp\n> > +++ b/src/libcamera/ipc_unixsocket.cpp\n> > @@ -7,6 +7,7 @@\n> >\n> >  #include \"libcamera/internal/ipc_unixsocket.h\"\n> >\n> > +#include <array>\n> >  #include <poll.h>\n> >  #include <string.h>\n> >  #include <sys/socket.h>\n> > @@ -68,7 +69,7 @@ LOG_DEFINE_CATEGORY(IPCUnixSocket)\n> >   */\n> >\n> >  IPCUnixSocket::IPCUnixSocket()\n> > -\t: fd_(-1), headerReceived_(false), notifier_(nullptr)\n> > +\t: headerReceived_(false), notifier_(nullptr)\n> >  {\n> >  }\n> >\n> > @@ -86,9 +87,9 @@ IPCUnixSocket::~IPCUnixSocket()\n> >   * to the remote process, where it can be used with IPCUnixSocket::bind() to\n> >   * bind the remote side socket.\n> >   *\n> > - * \\return A file descriptor on success, negative error code on failure\n> > + * \\return A file descriptor. It is valid on success or invalid otherwise.\n> >   */\n> > -int IPCUnixSocket::create()\n> > +UniqueFD IPCUnixSocket::create()\n> >  {\n> >  \tint sockets[2];\n> >  \tint ret;\n> > @@ -98,14 +99,18 @@ int IPCUnixSocket::create()\n> >  \t\tret = -errno;\n> >  \t\tLOG(IPCUnixSocket, Error)\n> >  \t\t\t<< \"Failed to create socket pair: \" << strerror(-ret);\n> > -\t\treturn ret;\n> > +\t\treturn {};\n> >  \t}\n> >\n> > -\tret = bind(sockets[0]);\n> > -\tif (ret)\n> > -\t\treturn ret;\n> > +\tstd::array<UniqueFD, 2> socketFds{\n> > +\t\tUniqueFD(sockets[0]),\n> > +\t\tUniqueFD(sockets[1]),\n> > +\t};\n> >\n> > -\treturn sockets[1];\n> > +\tif (bind(std::move(socketFds[0])) < 0)\n> > +\t\treturn {};\n> > +\n> > +\treturn std::move(socketFds[1]);\n> >  }\n> >\n> >  /**\n> > @@ -118,13 +123,13 @@ int IPCUnixSocket::create()\n> >   *\n> >   * \\return 0 on success or a negative error code otherwise\n> >   */\n> > -int IPCUnixSocket::bind(int fd)\n> > +int IPCUnixSocket::bind(UniqueFD fd)\n> >  {\n> >  \tif (isBound())\n> >  \t\treturn -EINVAL;\n> >\n> > -\tfd_ = fd;\n> > -\tnotifier_ = new EventNotifier(fd_, EventNotifier::Read);\n> > +\tfd_ = std::move(fd);\n> > +\tnotifier_ = new EventNotifier(fd_.get(), EventNotifier::Read);\n> >  \tnotifier_->activated.connect(this, &IPCUnixSocket::dataNotifier);\n> >\n> >  \treturn 0;\n> > @@ -143,9 +148,7 @@ void IPCUnixSocket::close()\n> >  \tdelete notifier_;\n> >  \tnotifier_ = nullptr;\n> >\n> > -\t::close(fd_);\n> > -\n> > -\tfd_ = -1;\n> > +\tfd_.reset();\n> >  \theaderReceived_ = false;\n> >  }\n> >\n> > @@ -155,7 +158,7 @@ void IPCUnixSocket::close()\n> >   */\n> >  bool IPCUnixSocket::isBound() const\n> >  {\n> > -\treturn fd_ != -1;\n> > +\treturn fd_.isValid();\n> >  }\n> >\n> >  /**\n> > @@ -182,7 +185,7 @@ int IPCUnixSocket::send(const Payload &payload)\n> >  \tif (!hdr.data && !hdr.fds)\n> >  \t\treturn -EINVAL;\n> >\n> > -\tret = ::send(fd_, &hdr, sizeof(hdr), 0);\n> > +\tret = ::send(fd_.get(), &hdr, sizeof(hdr), 0);\n> >  \tif (ret < 0) {\n> >  \t\tret = -errno;\n> >  \t\tLOG(IPCUnixSocket, Error)\n> > @@ -263,7 +266,7 @@ int IPCUnixSocket::sendData(const void *buffer, size_t length,\n> >  \tif (fds)\n> >  \t\tmemcpy(CMSG_DATA(cmsg), fds, num * sizeof(uint32_t));\n> >\n> > -\tif (sendmsg(fd_, &msg, 0) < 0) {\n> > +\tif (sendmsg(fd_.get(), &msg, 0) < 0) {\n> >  \t\tint ret = -errno;\n> >  \t\tLOG(IPCUnixSocket, Error)\n> >  \t\t\t<< \"Failed to sendmsg: \" << strerror(-ret);\n> > @@ -297,7 +300,7 @@ int IPCUnixSocket::recvData(void *buffer, size_t length,\n> >  \tmsg.msg_controllen = cmsg->cmsg_len;\n> >  \tmsg.msg_flags = 0;\n> >\n> > -\tif (recvmsg(fd_, &msg, 0) < 0) {\n> > +\tif (recvmsg(fd_.get(), &msg, 0) < 0) {\n> >  \t\tint ret = -errno;\n> >  \t\tif (ret != -EAGAIN)\n> >  \t\t\tLOG(IPCUnixSocket, Error)\n> > @@ -317,7 +320,7 @@ void IPCUnixSocket::dataNotifier()\n> >\n> >  \tif (!headerReceived_) {\n> >  \t\t/* Receive the header. */\n> > -\t\tret = ::recv(fd_, &header_, sizeof(header_), 0);\n> > +\t\tret = ::recv(fd_.get(), &header_, sizeof(header_), 0);\n> >  \t\tif (ret < 0) {\n> >  \t\t\tret = -errno;\n> >  \t\t\tLOG(IPCUnixSocket, Error)\n> > @@ -333,7 +336,7 @@ void IPCUnixSocket::dataNotifier()\n> >  \t * readyRead signal. The notifier will be reenabled by the receive()\n> >  \t * function.\n> >  \t */\n> > -\tstruct pollfd fds = { fd_, POLLIN, 0 };\n> > +\tstruct pollfd fds = { fd_.get(), POLLIN, 0 };\n> >  \tret = poll(&fds, 1, 0);\n> >  \tif (ret < 0)\n> >  \t\treturn;\n> > diff --git a/test/ipc/unixsocket.cpp b/test/ipc/unixsocket.cpp\n> > index 7270bf4d2fe7..414f1bfc9d12 100644\n> > --- a/test/ipc/unixsocket.cpp\n> > +++ b/test/ipc/unixsocket.cpp\n> > @@ -52,9 +52,9 @@ public:\n> >  \t\tipc_.readyRead.connect(this, &UnixSocketTestSlave::readyRead);\n> >  \t}\n> >\n> > -\tint run(int fd)\n> > +\tint run(UniqueFD fd)\n> >  \t{\n> > -\t\tif (ipc_.bind(fd)) {\n> > +\t\tif (ipc_.bind(std::move(fd))) {\n> >  \t\t\tcerr << \"Failed to connect to IPC channel\" << endl;\n> >  \t\t\treturn EXIT_FAILURE;\n> >  \t\t}\n> > @@ -360,11 +360,11 @@ protected:\n> >\n> >  \tint run()\n> >  \t{\n> > -\t\tint slavefd = ipc_.create();\n> > -\t\tif (slavefd < 0)\n> > +\t\tUniqueFD slavefd = ipc_.create();\n> > +\t\tif (!slavefd.isValid())\n> >  \t\t\treturn TestFail;\n> >\n> > -\t\tif (slaveStart(slavefd)) {\n> > +\t\tif (slaveStart(slavefd.release())) {\n> >  \t\t\tcerr << \"Failed to start slave\" << endl;\n> >  \t\t\treturn TestFail;\n> >  \t\t}\n> > @@ -496,9 +496,9 @@ private:\n> >  int main(int argc, char **argv)\n> >  {\n> >  \tif (argc == 2) {\n> > -\t\tint ipcfd = std::stoi(argv[1]);\n> > +\t\tUniqueFD ipcfd = UniqueFD(std::stoi(argv[1]));\n> >  \t\tUnixSocketTestSlave slave;\n> > -\t\treturn slave.run(ipcfd);\n> > +\t\treturn slave.run(std::move(ipcfd));\n> >  \t}\n> >\n> >  \treturn UnixSocketTest().execute();\n> > diff --git a/test/ipc/unixsocket_ipc.cpp b/test/ipc/unixsocket_ipc.cpp\n> > index ab5d25572d83..178ee1870056 100644\n> > --- a/test/ipc/unixsocket_ipc.cpp\n> > +++ b/test/ipc/unixsocket_ipc.cpp\n> > @@ -49,9 +49,9 @@ public:\n> >  \t\tipc_.readyRead.connect(this, &UnixSocketTestIPCSlave::readyRead);\n> >  \t}\n> >\n> > -\tint run(int fd)\n> > +\tint run(UniqueFD fd)\n> >  \t{\n> > -\t\tif (ipc_.bind(fd)) {\n> > +\t\tif (ipc_.bind(std::move(fd))) {\n> >  \t\t\tcerr << \"Failed to connect to IPC channel\" << endl;\n> >  \t\t\treturn EXIT_FAILURE;\n> >  \t\t}\n> > @@ -222,9 +222,9 @@ int main(int argc, char **argv)\n> >  {\n> >  \t/* IPCPipeUnixSocket passes IPA module path in argv[1] */\n> >  \tif (argc == 3) {\n> > -\t\tint ipcfd = std::stoi(argv[2]);\n> > +\t\tUniqueFD ipcfd = UniqueFD(std::stoi(argv[2]));\n> >  \t\tUnixSocketTestIPCSlave slave;\n> > -\t\treturn slave.run(ipcfd);\n> > +\t\treturn slave.run(std::move(ipcfd));\n> >  \t}\n> >\n> >  \treturn UnixSocketTestIPC().execute();\n> > diff --git a/utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl b/utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl\n> > index 764e7a3af63a..b65dc4cf31c5 100644\n> > --- a/utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl\n> > +++ b/utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl\n> > @@ -27,8 +27,9 @@\n> >  #include <libcamera/logging.h>\n> >\n> >  #include <libcamera/base/event_dispatcher.h>\n> > -#include <libcamera/base/thread.h>\n> >  #include <libcamera/base/log.h>\n> > +#include <libcamera/base/thread.h>\n> > +#include <libcamera/base/unique_fd.h>\n> >\n> >  #include \"libcamera/internal/camera_sensor.h\"\n> >  #include \"libcamera/internal/control_serializer.h\"\n> > @@ -122,9 +123,9 @@ public:\n> >  \t\t}\n> >  \t}\n> >\n> > -\tint init(std::unique_ptr<IPAModule> &ipam, int socketfd)\n> > +\tint init(std::unique_ptr<IPAModule> &ipam, UniqueFD socketfd)\n> >  \t{\n> > -\t\tif (socket_.bind(socketfd) < 0) {\n> > +\t\tif (socket_.bind(std::move(socketfd)) < 0) {\n> Is this bind() IPCUnixSocket::bind(UniqueFD fd) ?\n> do you need to move then ?\n>\n\nYes you do, sorry.\n\n> >  \t\t\tLOG({{proxy_worker_name}}, Error)\n> >  \t\t\t\t<< \"IPC socket binding failed\";\n> >  \t\t\treturn EXIT_FAILURE;\n> > @@ -203,10 +204,10 @@ int main(int argc, char **argv)\n> >  \t\treturn EXIT_FAILURE;\n> >  \t}\n> >\n> > -\tint fd = std::stoi(argv[2]);\n> > +\tUniqueFD fd(std::stoi(argv[2]));\n> >  \tLOG({{proxy_worker_name}}, Info)\n> >  \t\t<< \"Starting worker for IPA module \" << argv[1]\n> > -\t\t<< \" with IPC fd = \" << fd;\n> > +\t\t<< \" with IPC fd = \" << fd.get();\n> >\n> >  \tstd::unique_ptr<IPAModule> ipam = std::make_unique<IPAModule>(argv[1]);\n> >  \tif (!ipam->isValid() || !ipam->load()) {\n> > @@ -228,7 +229,7 @@ int main(int argc, char **argv)\n> >  \t}\n> >\n> >  \t{{proxy_worker_name}} proxyWorker;\n> > -\tint ret = proxyWorker.init(ipam, fd);\n> > +\tint ret = proxyWorker.init(ipam, std::move(fd));\n>\n> Same question\n>\n> Thanks\n>   j\n> >  \tif (ret < 0) {\n> >  \t\tLOG({{proxy_worker_name}}, Error)\n> >  \t\t\t<< \"Failed to initialize proxy worker\";\n> > --\n> > Regards,\n> >\n> > Laurent Pinchart\n> >","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 95720BF415\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 29 Nov 2021 15:53:46 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 59D27605A4;\n\tMon, 29 Nov 2021 16:53:46 +0100 (CET)","from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net\n\t[217.70.183.198])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 2616D60592\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 29 Nov 2021 16:53:44 +0100 (CET)","(Authenticated sender: jacopo@jmondi.org)\n\tby relay6-d.mail.gandi.net (Postfix) with ESMTPSA id 7710CC000E;\n\tMon, 29 Nov 2021 15:53:43 +0000 (UTC)"],"Date":"Mon, 29 Nov 2021 16:54:36 +0100","From":"Jacopo Mondi <jacopo@jmondi.org>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Message-ID":"<20211129155436.drel2ymii3phzqrp@uno.localdomain>","References":"<20211128235752.10836-1-laurent.pinchart@ideasonboard.com>\n\t<20211128235752.10836-11-laurent.pinchart@ideasonboard.com>\n\t<20211129153351.6r7m6qahvqcb2bcr@uno.localdomain>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20211129153351.6r7m6qahvqcb2bcr@uno.localdomain>","Subject":"Re: [libcamera-devel] [PATCH v3 10/17] libcamera: ipc_unixsocket:\n\tUse UniqueFD for a file descriptor","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>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":21357,"web_url":"https://patchwork.libcamera.org/comment/21357/","msgid":"<YaUGaB5qmp006puD@pendragon.ideasonboard.com>","date":"2021-11-29T16:57:12","subject":"Re: [libcamera-devel] [PATCH v3 10/17] libcamera: ipc_unixsocket:\n\tUse UniqueFD for a file descriptor","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jacopo,\n\nOn Mon, Nov 29, 2021 at 04:54:36PM +0100, Jacopo Mondi wrote:\n> On Mon, Nov 29, 2021 at 04:33:51PM +0100, Jacopo Mondi wrote:\n> > On Mon, Nov 29, 2021 at 01:57:45AM +0200, Laurent Pinchart wrote:\n> > > From: Hirokazu Honda <hiroh@chromium.org>\n> > >\n> > > IPCUnixSocket::create() creates two file descriptors. One of\n> > > them is stored in IPCUnixSocket and the other is returned to a\n> > > caller. This clarifies the ownership using UniqueFD.\n> > >\n> > > Signed-off-by: Hirokazu Honda <hiroh@chromium.org>\n> > > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > > ---\n> > > Changes since v2:\n> > >\n> > > - Pass UniqueFD to IPCUnixSocket::bind()\n> > > - Return {}\n> > > ---\n> > >  include/libcamera/internal/ipc_unixsocket.h   |  7 +--\n> > >  src/libcamera/ipc_pipe_unixsocket.cpp         |  8 ++--\n> > >  src/libcamera/ipc_unixsocket.cpp              | 43 ++++++++++---------\n> > >  test/ipc/unixsocket.cpp                       | 14 +++---\n> > >  test/ipc/unixsocket_ipc.cpp                   |  8 ++--\n> > >  .../module_ipa_proxy_worker.cpp.tmpl          | 13 +++---\n> > >  6 files changed, 49 insertions(+), 44 deletions(-)\n> > >\n> > > diff --git a/include/libcamera/internal/ipc_unixsocket.h b/include/libcamera/internal/ipc_unixsocket.h\n> > > index 5010b66a2bda..3963d182ffa6 100644\n> > > --- a/include/libcamera/internal/ipc_unixsocket.h\n> > > +++ b/include/libcamera/internal/ipc_unixsocket.h\n> > > @@ -12,6 +12,7 @@\n> > >  #include <vector>\n> > >\n> > >  #include <libcamera/base/signal.h>\n> > > +#include <libcamera/base/unique_fd.h>\n> > >\n> > >  namespace libcamera {\n> > >\n> > > @@ -28,8 +29,8 @@ public:\n> > >  \tIPCUnixSocket();\n> > >  \t~IPCUnixSocket();\n> > >\n> > > -\tint create();\n> > > -\tint bind(int fd);\n> > > +\tUniqueFD create();\n> > > +\tint bind(UniqueFD fd);\n> > >  \tvoid close();\n> > >  \tbool isBound() const;\n> > >\n> > > @@ -49,7 +50,7 @@ private:\n> > >\n> > >  \tvoid dataNotifier();\n> > >\n> > > -\tint fd_;\n> > > +\tUniqueFD fd_;\n> > >  \tbool headerReceived_;\n> > >  \tstruct Header header_;\n> > >  \tEventNotifier *notifier_;\n> > > diff --git a/src/libcamera/ipc_pipe_unixsocket.cpp b/src/libcamera/ipc_pipe_unixsocket.cpp\n> > > index 533560cf95d3..65277500ff42 100644\n> > > --- a/src/libcamera/ipc_pipe_unixsocket.cpp\n> > > +++ b/src/libcamera/ipc_pipe_unixsocket.cpp\n> > > @@ -31,14 +31,14 @@ IPCPipeUnixSocket::IPCPipeUnixSocket(const char *ipaModulePath,\n> > >  \targs.push_back(ipaModulePath);\n> > >\n> > >  \tsocket_ = std::make_unique<IPCUnixSocket>();\n> > > -\tint fd = socket_->create();\n> > > -\tif (fd < 0) {\n> > > +\tUniqueFD fd = socket_->create();\n> > > +\tif (!fd.isValid()) {\n> > >  \t\tLOG(IPCPipe, Error) << \"Failed to create socket\";\n> > >  \t\treturn;\n> > >  \t}\n> > >  \tsocket_->readyRead.connect(this, &IPCPipeUnixSocket::readyRead);\n> > > -\targs.push_back(std::to_string(fd));\n> > > -\tfds.push_back(fd);\n> >\n> > Was in the previous version fd leaked ??\n\nIt seems to be leaked in this version too actually... I'll test it.\n\n> > > +\targs.push_back(std::to_string(fd.get()));\n> > > +\tfds.push_back(fd.release());\n> > >\n> > >  \tproc_ = std::make_unique<Process>();\n> > >  \tint ret = proc_->start(ipaProxyWorkerPath, args, fds);\n> > > diff --git a/src/libcamera/ipc_unixsocket.cpp b/src/libcamera/ipc_unixsocket.cpp\n> > > index bd32fca3a678..1980d374cea8 100644\n> > > --- a/src/libcamera/ipc_unixsocket.cpp\n> > > +++ b/src/libcamera/ipc_unixsocket.cpp\n> > > @@ -7,6 +7,7 @@\n> > >\n> > >  #include \"libcamera/internal/ipc_unixsocket.h\"\n> > >\n> > > +#include <array>\n> > >  #include <poll.h>\n> > >  #include <string.h>\n> > >  #include <sys/socket.h>\n> > > @@ -68,7 +69,7 @@ LOG_DEFINE_CATEGORY(IPCUnixSocket)\n> > >   */\n> > >\n> > >  IPCUnixSocket::IPCUnixSocket()\n> > > -\t: fd_(-1), headerReceived_(false), notifier_(nullptr)\n> > > +\t: headerReceived_(false), notifier_(nullptr)\n> > >  {\n> > >  }\n> > >\n> > > @@ -86,9 +87,9 @@ IPCUnixSocket::~IPCUnixSocket()\n> > >   * to the remote process, where it can be used with IPCUnixSocket::bind() to\n> > >   * bind the remote side socket.\n> > >   *\n> > > - * \\return A file descriptor on success, negative error code on failure\n> > > + * \\return A file descriptor. It is valid on success or invalid otherwise.\n> > >   */\n> > > -int IPCUnixSocket::create()\n> > > +UniqueFD IPCUnixSocket::create()\n> > >  {\n> > >  \tint sockets[2];\n> > >  \tint ret;\n> > > @@ -98,14 +99,18 @@ int IPCUnixSocket::create()\n> > >  \t\tret = -errno;\n> > >  \t\tLOG(IPCUnixSocket, Error)\n> > >  \t\t\t<< \"Failed to create socket pair: \" << strerror(-ret);\n> > > -\t\treturn ret;\n> > > +\t\treturn {};\n> > >  \t}\n> > >\n> > > -\tret = bind(sockets[0]);\n> > > -\tif (ret)\n> > > -\t\treturn ret;\n> > > +\tstd::array<UniqueFD, 2> socketFds{\n> > > +\t\tUniqueFD(sockets[0]),\n> > > +\t\tUniqueFD(sockets[1]),\n> > > +\t};\n> > >\n> > > -\treturn sockets[1];\n> > > +\tif (bind(std::move(socketFds[0])) < 0)\n> > > +\t\treturn {};\n> > > +\n> > > +\treturn std::move(socketFds[1]);\n> > >  }\n> > >\n> > >  /**\n> > > @@ -118,13 +123,13 @@ int IPCUnixSocket::create()\n> > >   *\n> > >   * \\return 0 on success or a negative error code otherwise\n> > >   */\n> > > -int IPCUnixSocket::bind(int fd)\n> > > +int IPCUnixSocket::bind(UniqueFD fd)\n> > >  {\n> > >  \tif (isBound())\n> > >  \t\treturn -EINVAL;\n> > >\n> > > -\tfd_ = fd;\n> > > -\tnotifier_ = new EventNotifier(fd_, EventNotifier::Read);\n> > > +\tfd_ = std::move(fd);\n> > > +\tnotifier_ = new EventNotifier(fd_.get(), EventNotifier::Read);\n> > >  \tnotifier_->activated.connect(this, &IPCUnixSocket::dataNotifier);\n> > >\n> > >  \treturn 0;\n> > > @@ -143,9 +148,7 @@ void IPCUnixSocket::close()\n> > >  \tdelete notifier_;\n> > >  \tnotifier_ = nullptr;\n> > >\n> > > -\t::close(fd_);\n> > > -\n> > > -\tfd_ = -1;\n> > > +\tfd_.reset();\n> > >  \theaderReceived_ = false;\n> > >  }\n> > >\n> > > @@ -155,7 +158,7 @@ void IPCUnixSocket::close()\n> > >   */\n> > >  bool IPCUnixSocket::isBound() const\n> > >  {\n> > > -\treturn fd_ != -1;\n> > > +\treturn fd_.isValid();\n> > >  }\n> > >\n> > >  /**\n> > > @@ -182,7 +185,7 @@ int IPCUnixSocket::send(const Payload &payload)\n> > >  \tif (!hdr.data && !hdr.fds)\n> > >  \t\treturn -EINVAL;\n> > >\n> > > -\tret = ::send(fd_, &hdr, sizeof(hdr), 0);\n> > > +\tret = ::send(fd_.get(), &hdr, sizeof(hdr), 0);\n> > >  \tif (ret < 0) {\n> > >  \t\tret = -errno;\n> > >  \t\tLOG(IPCUnixSocket, Error)\n> > > @@ -263,7 +266,7 @@ int IPCUnixSocket::sendData(const void *buffer, size_t length,\n> > >  \tif (fds)\n> > >  \t\tmemcpy(CMSG_DATA(cmsg), fds, num * sizeof(uint32_t));\n> > >\n> > > -\tif (sendmsg(fd_, &msg, 0) < 0) {\n> > > +\tif (sendmsg(fd_.get(), &msg, 0) < 0) {\n> > >  \t\tint ret = -errno;\n> > >  \t\tLOG(IPCUnixSocket, Error)\n> > >  \t\t\t<< \"Failed to sendmsg: \" << strerror(-ret);\n> > > @@ -297,7 +300,7 @@ int IPCUnixSocket::recvData(void *buffer, size_t length,\n> > >  \tmsg.msg_controllen = cmsg->cmsg_len;\n> > >  \tmsg.msg_flags = 0;\n> > >\n> > > -\tif (recvmsg(fd_, &msg, 0) < 0) {\n> > > +\tif (recvmsg(fd_.get(), &msg, 0) < 0) {\n> > >  \t\tint ret = -errno;\n> > >  \t\tif (ret != -EAGAIN)\n> > >  \t\t\tLOG(IPCUnixSocket, Error)\n> > > @@ -317,7 +320,7 @@ void IPCUnixSocket::dataNotifier()\n> > >\n> > >  \tif (!headerReceived_) {\n> > >  \t\t/* Receive the header. */\n> > > -\t\tret = ::recv(fd_, &header_, sizeof(header_), 0);\n> > > +\t\tret = ::recv(fd_.get(), &header_, sizeof(header_), 0);\n> > >  \t\tif (ret < 0) {\n> > >  \t\t\tret = -errno;\n> > >  \t\t\tLOG(IPCUnixSocket, Error)\n> > > @@ -333,7 +336,7 @@ void IPCUnixSocket::dataNotifier()\n> > >  \t * readyRead signal. The notifier will be reenabled by the receive()\n> > >  \t * function.\n> > >  \t */\n> > > -\tstruct pollfd fds = { fd_, POLLIN, 0 };\n> > > +\tstruct pollfd fds = { fd_.get(), POLLIN, 0 };\n> > >  \tret = poll(&fds, 1, 0);\n> > >  \tif (ret < 0)\n> > >  \t\treturn;\n> > > diff --git a/test/ipc/unixsocket.cpp b/test/ipc/unixsocket.cpp\n> > > index 7270bf4d2fe7..414f1bfc9d12 100644\n> > > --- a/test/ipc/unixsocket.cpp\n> > > +++ b/test/ipc/unixsocket.cpp\n> > > @@ -52,9 +52,9 @@ public:\n> > >  \t\tipc_.readyRead.connect(this, &UnixSocketTestSlave::readyRead);\n> > >  \t}\n> > >\n> > > -\tint run(int fd)\n> > > +\tint run(UniqueFD fd)\n> > >  \t{\n> > > -\t\tif (ipc_.bind(fd)) {\n> > > +\t\tif (ipc_.bind(std::move(fd))) {\n> > >  \t\t\tcerr << \"Failed to connect to IPC channel\" << endl;\n> > >  \t\t\treturn EXIT_FAILURE;\n> > >  \t\t}\n> > > @@ -360,11 +360,11 @@ protected:\n> > >\n> > >  \tint run()\n> > >  \t{\n> > > -\t\tint slavefd = ipc_.create();\n> > > -\t\tif (slavefd < 0)\n> > > +\t\tUniqueFD slavefd = ipc_.create();\n> > > +\t\tif (!slavefd.isValid())\n> > >  \t\t\treturn TestFail;\n> > >\n> > > -\t\tif (slaveStart(slavefd)) {\n> > > +\t\tif (slaveStart(slavefd.release())) {\n> > >  \t\t\tcerr << \"Failed to start slave\" << endl;\n> > >  \t\t\treturn TestFail;\n> > >  \t\t}\n> > > @@ -496,9 +496,9 @@ private:\n> > >  int main(int argc, char **argv)\n> > >  {\n> > >  \tif (argc == 2) {\n> > > -\t\tint ipcfd = std::stoi(argv[1]);\n> > > +\t\tUniqueFD ipcfd = UniqueFD(std::stoi(argv[1]));\n> > >  \t\tUnixSocketTestSlave slave;\n> > > -\t\treturn slave.run(ipcfd);\n> > > +\t\treturn slave.run(std::move(ipcfd));\n> > >  \t}\n> > >\n> > >  \treturn UnixSocketTest().execute();\n> > > diff --git a/test/ipc/unixsocket_ipc.cpp b/test/ipc/unixsocket_ipc.cpp\n> > > index ab5d25572d83..178ee1870056 100644\n> > > --- a/test/ipc/unixsocket_ipc.cpp\n> > > +++ b/test/ipc/unixsocket_ipc.cpp\n> > > @@ -49,9 +49,9 @@ public:\n> > >  \t\tipc_.readyRead.connect(this, &UnixSocketTestIPCSlave::readyRead);\n> > >  \t}\n> > >\n> > > -\tint run(int fd)\n> > > +\tint run(UniqueFD fd)\n> > >  \t{\n> > > -\t\tif (ipc_.bind(fd)) {\n> > > +\t\tif (ipc_.bind(std::move(fd))) {\n> > >  \t\t\tcerr << \"Failed to connect to IPC channel\" << endl;\n> > >  \t\t\treturn EXIT_FAILURE;\n> > >  \t\t}\n> > > @@ -222,9 +222,9 @@ int main(int argc, char **argv)\n> > >  {\n> > >  \t/* IPCPipeUnixSocket passes IPA module path in argv[1] */\n> > >  \tif (argc == 3) {\n> > > -\t\tint ipcfd = std::stoi(argv[2]);\n> > > +\t\tUniqueFD ipcfd = UniqueFD(std::stoi(argv[2]));\n> > >  \t\tUnixSocketTestIPCSlave slave;\n> > > -\t\treturn slave.run(ipcfd);\n> > > +\t\treturn slave.run(std::move(ipcfd));\n> > >  \t}\n> > >\n> > >  \treturn UnixSocketTestIPC().execute();\n> > > diff --git a/utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl b/utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl\n> > > index 764e7a3af63a..b65dc4cf31c5 100644\n> > > --- a/utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl\n> > > +++ b/utils/ipc/generators/libcamera_templates/module_ipa_proxy_worker.cpp.tmpl\n> > > @@ -27,8 +27,9 @@\n> > >  #include <libcamera/logging.h>\n> > >\n> > >  #include <libcamera/base/event_dispatcher.h>\n> > > -#include <libcamera/base/thread.h>\n> > >  #include <libcamera/base/log.h>\n> > > +#include <libcamera/base/thread.h>\n> > > +#include <libcamera/base/unique_fd.h>\n> > >\n> > >  #include \"libcamera/internal/camera_sensor.h\"\n> > >  #include \"libcamera/internal/control_serializer.h\"\n> > > @@ -122,9 +123,9 @@ public:\n> > >  \t\t}\n> > >  \t}\n> > >\n> > > -\tint init(std::unique_ptr<IPAModule> &ipam, int socketfd)\n> > > +\tint init(std::unique_ptr<IPAModule> &ipam, UniqueFD socketfd)\n> > >  \t{\n> > > -\t\tif (socket_.bind(socketfd) < 0) {\n> > > +\t\tif (socket_.bind(std::move(socketfd)) < 0) {\n> >\n> > Is this bind() IPCUnixSocket::bind(UniqueFD fd) ?\n> > do you need to move then ?\n> \n> Yes you do, sorry.\n\nYou're right :-)\n\n> > >  \t\t\tLOG({{proxy_worker_name}}, Error)\n> > >  \t\t\t\t<< \"IPC socket binding failed\";\n> > >  \t\t\treturn EXIT_FAILURE;\n> > > @@ -203,10 +204,10 @@ int main(int argc, char **argv)\n> > >  \t\treturn EXIT_FAILURE;\n> > >  \t}\n> > >\n> > > -\tint fd = std::stoi(argv[2]);\n> > > +\tUniqueFD fd(std::stoi(argv[2]));\n> > >  \tLOG({{proxy_worker_name}}, Info)\n> > >  \t\t<< \"Starting worker for IPA module \" << argv[1]\n> > > -\t\t<< \" with IPC fd = \" << fd;\n> > > +\t\t<< \" with IPC fd = \" << fd.get();\n> > >\n> > >  \tstd::unique_ptr<IPAModule> ipam = std::make_unique<IPAModule>(argv[1]);\n> > >  \tif (!ipam->isValid() || !ipam->load()) {\n> > > @@ -228,7 +229,7 @@ int main(int argc, char **argv)\n> > >  \t}\n> > >\n> > >  \t{{proxy_worker_name}} proxyWorker;\n> > > -\tint ret = proxyWorker.init(ipam, fd);\n> > > +\tint ret = proxyWorker.init(ipam, std::move(fd));\n> >\n> > Same question\n> >\n> > >  \tif (ret < 0) {\n> > >  \t\tLOG({{proxy_worker_name}}, Error)\n> > >  \t\t\t<< \"Failed to initialize proxy worker\";","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id E043CBDB13\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 29 Nov 2021 16:57:38 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 3FF16605A4;\n\tMon, 29 Nov 2021 17:57:38 +0100 (CET)","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 8620E60592\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 29 Nov 2021 17:57:36 +0100 (CET)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id F1B4F2A5;\n\tMon, 29 Nov 2021 17:57:35 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"bl5C4Lrd\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1638205056;\n\tbh=aCP7OHbxKJRuO39nfHzhCNomX/rU1L85dMAHS+JI21w=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=bl5C4LrdDvvu2CLAW9z2RADzo9f7vhl09puVxeKRaeIr5spxGoBBpRXMguralP4Vy\n\tnpFqW0pwjrfGlPLrTWKftmsS4suRAyv7HUopVdCp1Fonwdebaz/gMsv4t9nPZj2oX+\n\t3EC9/3xE0SUSfefxFh62xHRLxNogsBtSKPnTxzhg=","Date":"Mon, 29 Nov 2021 18:57:12 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jacopo Mondi <jacopo@jmondi.org>","Message-ID":"<YaUGaB5qmp006puD@pendragon.ideasonboard.com>","References":"<20211128235752.10836-1-laurent.pinchart@ideasonboard.com>\n\t<20211128235752.10836-11-laurent.pinchart@ideasonboard.com>\n\t<20211129153351.6r7m6qahvqcb2bcr@uno.localdomain>\n\t<20211129155436.drel2ymii3phzqrp@uno.localdomain>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20211129155436.drel2ymii3phzqrp@uno.localdomain>","Subject":"Re: [libcamera-devel] [PATCH v3 10/17] libcamera: ipc_unixsocket:\n\tUse UniqueFD for a file descriptor","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>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]