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