<div dir="ltr"><div dir="ltr">Hi Laurent,</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Jun 7, 2021 at 6:15 PM Hirokazu Honda <<a href="mailto:hiroh@chromium.org">hiroh@chromium.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr">Hi Laurent,</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Jun 7, 2021 at 3:30 AM Laurent Pinchart <<a href="mailto:laurent.pinchart@ideasonboard.com" target="_blank">laurent.pinchart@ideasonboard.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi Hiro,<br>
<br>
Thank you for the patch.<br>
<br>
On Thu, Apr 15, 2021 at 05:38:41PM +0900, Hirokazu Honda wrote:<br>
> IPCUnixSocket::create() creates two file descriptors. One of<br>
> them is stored in IPCUnixSocket and the other is returned to a<br>
> caller. This clarifies the ownership using ScopedFD.<br>
> <br>
> Signed-off-by: Hirokazu Honda <<a href="mailto:hiroh@chromium.org" target="_blank">hiroh@chromium.org</a>><br>
> ---<br>
>  include/libcamera/internal/ipc_unixsocket.h |  5 +--<br>
>  src/libcamera/ipc_pipe_unixsocket.cpp       |  8 ++---<br>
>  src/libcamera/ipc_unixsocket.cpp            | 40 ++++++++++-----------<br>
>  test/ipc/unixsocket.cpp                     |  6 ++--<br>
>  4 files changed, 30 insertions(+), 29 deletions(-)<br>
> <br>
> diff --git a/include/libcamera/internal/ipc_unixsocket.h b/include/libcamera/internal/ipc_unixsocket.h<br>
> index e871b650..c06fee47 100644<br>
> --- a/include/libcamera/internal/ipc_unixsocket.h<br>
> +++ b/include/libcamera/internal/ipc_unixsocket.h<br>
> @@ -12,6 +12,7 @@<br>
>  #include <sys/types.h><br>
>  #include <vector><br>
>  <br>
> +#include <libcamera/scoped_file_descriptor.h><br>
>  #include <libcamera/signal.h><br>
>  <br>
>  namespace libcamera {<br>
> @@ -29,7 +30,7 @@ public:<br>
>       IPCUnixSocket();<br>
>       ~IPCUnixSocket();<br>
>  <br>
> -     int create();<br>
> +     ScopedFD create();<br>
>       int bind(int fd);<br>
>       void close();<br>
>       bool isBound() const;<br>
> @@ -50,7 +51,7 @@ private:<br>
>  <br>
>       void dataNotifier(EventNotifier *notifier);<br>
>  <br>
> -     int fd_;<br>
> +     ScopedFD fd_;<br>
>       bool headerReceived_;<br>
>       struct Header header_;<br>
>       EventNotifier *notifier_;<br>
> diff --git a/src/libcamera/ipc_pipe_unixsocket.cpp b/src/libcamera/ipc_pipe_unixsocket.cpp<br>
> index db0e260f..1997643f 100644<br>
> --- a/src/libcamera/ipc_pipe_unixsocket.cpp<br>
> +++ b/src/libcamera/ipc_pipe_unixsocket.cpp<br>
> @@ -30,14 +30,14 @@ IPCPipeUnixSocket::IPCPipeUnixSocket(const char *ipaModulePath,<br>
>       args.push_back(ipaModulePath);<br>
>  <br>
>       socket_ = std::make_unique<IPCUnixSocket>();<br>
> -     int fd = socket_->create();<br>
> -     if (fd < 0) {<br>
> +     ScopedFD fd = socket_->create();<br>
> +     if (!fd.isValid()) {<br>
>               LOG(IPCPipe, Error) << "Failed to create socket";<br>
>               return;<br>
>       }<br>
>       socket_->readyRead.connect(this, &IPCPipeUnixSocket::readyRead);<br>
> -     args.push_back(std::to_string(fd));<br>
> -     fds.push_back(fd);<br>
> +     args.push_back(std::to_string(fd.get()));<br>
> +     fds.push_back(fd.release());<br>
>  <br>
>       proc_ = std::make_unique<Process>();<br>
>       int ret = proc_->start(ipaProxyWorkerPath, args, fds);<br>
> diff --git a/src/libcamera/ipc_unixsocket.cpp b/src/libcamera/ipc_unixsocket.cpp<br>
> index fdb359f7..2da43188 100644<br>
> --- a/src/libcamera/ipc_unixsocket.cpp<br>
> +++ b/src/libcamera/ipc_unixsocket.cpp<br>
> @@ -68,7 +68,7 @@ LOG_DEFINE_CATEGORY(IPCUnixSocket)<br>
>   */<br>
>  <br>
>  IPCUnixSocket::IPCUnixSocket()<br>
> -     : fd_(-1), headerReceived_(false), notifier_(nullptr)<br>
> +     : headerReceived_(false), notifier_(nullptr)<br>
>  {<br>
>  }<br>
>  <br>
> @@ -86,9 +86,9 @@ IPCUnixSocket::~IPCUnixSocket()<br>
>   * the remote process, where it can be used with IPCUnixSocket::bind() to bind<br>
>   * the remote side socket.<br>
>   *<br>
> - * \return A file descriptor on success, negative error code on failure<br>
> + * \return A file descriptor. It is valid on success or invalid otherwise.<br>
>   */<br>
> -int IPCUnixSocket::create()<br>
> +ScopedFD IPCUnixSocket::create()<br>
>  {<br>
>       int sockets[2];<br>
>       int ret;<br>
> @@ -98,14 +98,13 @@ int IPCUnixSocket::create()<br>
>               ret = -errno;<br>
>               LOG(IPCUnixSocket, Error)<br>
>                       << "Failed to create socket pair: " << strerror(-ret);<br>
> -             return ret;<br>
> +             return ScopedFD();<br>
>       }<br>
>  <br>
> -     ret = bind(sockets[0]);<br>
> -     if (ret)<br>
> -             return ret;<br>
> +     if (bind(sockets[0]) < 0)<br>
> +             return ScopedFD();<br>
>  <br>
> -     return sockets[1];<br>
> +     return ScopedFD(sockets[1]);<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -116,15 +115,18 @@ int IPCUnixSocket::create()<br>
>   * by the file descriptor \a fd. The file descriptor is obtained from the<br>
>   * IPCUnixSocket::create() method.<br>
>   *<br>
> - * \return 0 on success or a negative error code otherwise<br>
> + * \return 0 on success or a negative error code otherwise.<br>
> + *<br>
> + * \todo This argument should be ScopedFD because bind() takes over the<br>
> + * ownership.<br>
<br>
Could you address this ?<br>
<br></blockquote></div></div></blockquote><div><br></div><div>I tried to address this and recalled that I gave up doing this right now because some generated code in src/libcamera/proxy/worker/ uses the function with a numerical integer.</div><div><br></div><div>-Hiro</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
>   */<br>
>  int IPCUnixSocket::bind(int fd)<br>
>  {<br>
>       if (isBound())<br>
>               return -EINVAL;<br>
>  <br>
> -     fd_ = fd;<br>
> -     notifier_ = new EventNotifier(fd_, EventNotifier::Read);<br>
> +     fd_ = ScopedFD(fd);<br>
> +     notifier_ = new EventNotifier(fd_.get(), EventNotifier::Read);<br>
>       notifier_->activated.connect(this, &IPCUnixSocket::dataNotifier);<br>
>  <br>
>       return 0;<br>
> @@ -143,9 +145,7 @@ void IPCUnixSocket::close()<br>
>       delete notifier_;<br>
>       notifier_ = nullptr;<br>
>  <br>
> -     ::close(fd_);<br>
> -<br>
> -     fd_ = -1;<br>
> +     fd_.reset();<br>
>       headerReceived_ = false;<br>
>  }<br>
>  <br>
> @@ -155,7 +155,7 @@ void IPCUnixSocket::close()<br>
>   */<br>
>  bool IPCUnixSocket::isBound() const<br>
>  {<br>
> -     return fd_ != -1;<br>
> +     return fd_.isValid();<br>
>  }<br>
>  <br>
>  /**<br>
> @@ -182,7 +182,7 @@ int IPCUnixSocket::send(const Payload &payload)<br>
>       if (!hdr.data && !hdr.fds)<br>
>               return -EINVAL;<br>
>  <br>
> -     ret = ::send(fd_, &hdr, sizeof(hdr), 0);<br>
> +     ret = ::send(fd_.get(), &hdr, sizeof(hdr), 0);<br>
>       if (ret < 0) {<br>
>               ret = -errno;<br>
>               LOG(IPCUnixSocket, Error)<br>
> @@ -262,7 +262,7 @@ int IPCUnixSocket::sendData(const void *buffer, size_t length,<br>
>       msg.msg_flags = 0;<br>
>       memcpy(CMSG_DATA(cmsg), fds, num * sizeof(uint32_t));<br>
>  <br>
> -     if (sendmsg(fd_, &msg, 0) < 0) {<br>
> +     if (sendmsg(fd_.get(), &msg, 0) < 0) {<br>
>               int ret = -errno;<br>
>               LOG(IPCUnixSocket, Error)<br>
>                       << "Failed to sendmsg: " << strerror(-ret);<br>
> @@ -296,7 +296,7 @@ int IPCUnixSocket::recvData(void *buffer, size_t length,<br>
>       msg.msg_controllen = cmsg->cmsg_len;<br>
>       msg.msg_flags = 0;<br>
>  <br>
> -     if (recvmsg(fd_, &msg, 0) < 0) {<br>
> +     if (recvmsg(fd_.get(), &msg, 0) < 0) {<br>
>               int ret = -errno;<br>
>               if (ret != -EAGAIN)<br>
>                       LOG(IPCUnixSocket, Error)<br>
> @@ -315,7 +315,7 @@ void IPCUnixSocket::dataNotifier([[maybe_unused]] EventNotifier *notifier)<br>
>  <br>
>       if (!headerReceived_) {<br>
>               /* Receive the header. */<br>
> -             ret = ::recv(fd_, &header_, sizeof(header_), 0);<br>
> +             ret = ::recv(fd_.get(), &header_, sizeof(header_), 0);<br>
>               if (ret < 0) {<br>
>                       ret = -errno;<br>
>                       LOG(IPCUnixSocket, Error)<br>
> @@ -331,7 +331,7 @@ void IPCUnixSocket::dataNotifier([[maybe_unused]] EventNotifier *notifier)<br>
>        * readyRead signal. The notifier will be reenabled by the receive()<br>
>        * method.<br>
>        */<br>
> -     struct pollfd fds = { fd_, POLLIN, 0 };<br>
> +     struct pollfd fds = { fd_.get(), POLLIN, 0 };<br>
>       ret = poll(&fds, 1, 0);<br>
>       if (ret < 0)<br>
>               return;<br>
> diff --git a/test/ipc/unixsocket.cpp b/test/ipc/unixsocket.cpp<br>
> index 80157b34..9ca0467b 100644<br>
> --- a/test/ipc/unixsocket.cpp<br>
> +++ b/test/ipc/unixsocket.cpp<br>
> @@ -359,11 +359,11 @@ protected:<br>
>  <br>
>       int run()<br>
>       {<br>
> -             int slavefd = ipc_.create();<br>
> -             if (slavefd < 0)<br>
> +             ScopedFD slavefd = ipc_.create();<br>
> +             if (!slavefd.isValid())<br>
>                       return TestFail;<br>
>  <br>
> -             if (slaveStart(slavefd)) {<br>
> +             if (slaveStart(slavefd.release())) {<br>
<br>
Should the slaveStart() function take a ScopedFD && ?<br>
<br></blockquote><div><br></div><div>Which is correct, slaveStart() should take the ownership of a file descriptor, or the ownership should still be owned by a caller?</div><div><br></div><div>-Hiro</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
>                       cerr << "Failed to start slave" << endl;<br>
>                       return TestFail;<br>
>               }<br>
<br>
-- <br>
Regards,<br>
<br>
Laurent Pinchart<br>
</blockquote></div></div>
</blockquote></div></div>