[{"id":38549,"web_url":"https://patchwork.libcamera.org/comment/38549/","msgid":"<85cy099v3s.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","date":"2026-04-08T18:15:35","subject":"Re: [PATCH v2 03/42] libcamera: Replace plain pointers with\n\tstd::unique<>","submitter":{"id":177,"url":"https://patchwork.libcamera.org/api/people/177/","name":"Milan Zamazal","email":"mzamazal@redhat.com"},"content":"Laurent Pinchart <laurent.pinchart@ideasonboard.com> writes:\n\n> libcamera uses std::unique_ptr<> to simplify life time management of\n> objects and avoid leaks. For historical reasons there are a fair number\n> of plain pointers with manual memory management. Replace them with\n> std::unique_ptr<> when the conversion is simple.\n>\n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nReviewed-by: Milan Zamazal <mzamazal@redhat.com>\n\n> ---\n>  .../guides/application-developer.rst          |  5 +++--\n>  .../internal/device_enumerator_udev.h         |  2 +-\n>  include/libcamera/internal/ipc_unixsocket.h   |  3 ++-\n>  include/libcamera/internal/v4l2_device.h      |  2 +-\n>  include/libcamera/internal/v4l2_videodevice.h | 12 +++++-----\n>  src/apps/qcam/main.cpp                        |  5 ++---\n>  src/apps/qcam/main_window.cpp                 | 11 +++++-----\n>  src/apps/qcam/main_window.h                   |  2 +-\n>  src/libcamera/device_enumerator_udev.cpp      |  6 ++---\n>  src/libcamera/ipc_unixsocket.cpp              |  7 +++---\n>  src/libcamera/v4l2_device.cpp                 |  5 +++--\n>  src/libcamera/v4l2_videodevice.cpp            | 22 ++++++++-----------\n>  src/v4l2/v4l2_camera.cpp                      |  7 +++---\n>  src/v4l2/v4l2_camera.h                        |  2 +-\n>  src/v4l2/v4l2_compat_manager.cpp              | 18 +++++----------\n>  src/v4l2/v4l2_compat_manager.h                |  2 +-\n>  16 files changed, 49 insertions(+), 62 deletions(-)\n>\n> diff --git a/Documentation/guides/application-developer.rst b/Documentation/guides/application-developer.rst\n> index 918077af1d22..fd91cc503568 100644\n> --- a/Documentation/guides/application-developer.rst\n> +++ b/Documentation/guides/application-developer.rst\n> @@ -279,7 +279,8 @@ as the parameter of the ``FrameBufferAllocator::buffers()`` function.\n>  \n>  .. code:: cpp\n>  \n> -   FrameBufferAllocator *allocator = new FrameBufferAllocator(camera);\n> +   std::unique_ptr<FrameBufferAllocator> allocator =\n> +       std::make_unique<FrameBufferAllocator>(camera);\n>  \n>     for (StreamConfiguration &cfg : *config) {\n>         int ret = allocator->allocate(cfg.stream());\n> @@ -539,7 +540,7 @@ uses, so needs to do the following:\n>  \n>     camera->stop();\n>     allocator->free(stream);\n> -   delete allocator;\n> +   allocator.reset();\n>     camera->release();\n>     camera.reset();\n>     cm->stop();\n> diff --git a/include/libcamera/internal/device_enumerator_udev.h b/include/libcamera/internal/device_enumerator_udev.h\n> index 0bf78b551e75..1ce988ab84d1 100644\n> --- a/include/libcamera/internal/device_enumerator_udev.h\n> +++ b/include/libcamera/internal/device_enumerator_udev.h\n> @@ -69,7 +69,7 @@ private:\n>  \n>  \tstruct udev *udev_;\n>  \tstruct udev_monitor *monitor_;\n> -\tEventNotifier *notifier_;\n> +\tstd::unique_ptr<EventNotifier> notifier_;\n>  \n>  \tstd::set<dev_t> orphans_;\n>  \tstd::unordered_set<dev_t> devices_;\n> diff --git a/include/libcamera/internal/ipc_unixsocket.h b/include/libcamera/internal/ipc_unixsocket.h\n> index 48bb7a9422b5..57614fa3f0c7 100644\n> --- a/include/libcamera/internal/ipc_unixsocket.h\n> +++ b/include/libcamera/internal/ipc_unixsocket.h\n> @@ -7,6 +7,7 @@\n>  \n>  #pragma once\n>  \n> +#include <memory>\n>  #include <stdint.h>\n>  #include <sys/types.h>\n>  #include <vector>\n> @@ -53,7 +54,7 @@ private:\n>  \tUniqueFD fd_;\n>  \tbool headerReceived_;\n>  \tstruct Header header_;\n> -\tEventNotifier *notifier_;\n> +\tstd::unique_ptr<EventNotifier> notifier_;\n>  };\n>  \n>  } /* namespace libcamera */\n> diff --git a/include/libcamera/internal/v4l2_device.h b/include/libcamera/internal/v4l2_device.h\n> index dbbd118abd00..8c4c59bf7773 100644\n> --- a/include/libcamera/internal/v4l2_device.h\n> +++ b/include/libcamera/internal/v4l2_device.h\n> @@ -89,7 +89,7 @@ private:\n>  \tstd::string deviceNode_;\n>  \tUniqueFD fd_;\n>  \n> -\tEventNotifier *fdEventNotifier_;\n> +\tstd::unique_ptr<EventNotifier> fdEventNotifier_;\n>  \tbool frameStartEnabled_;\n>  };\n>  \n> diff --git a/include/libcamera/internal/v4l2_videodevice.h b/include/libcamera/internal/v4l2_videodevice.h\n> index 57db0036db6b..10367e4e178a 100644\n> --- a/include/libcamera/internal/v4l2_videodevice.h\n> +++ b/include/libcamera/internal/v4l2_videodevice.h\n> @@ -280,10 +280,10 @@ private:\n>  \tenum v4l2_buf_type bufferType_;\n>  \tenum v4l2_memory memoryType_;\n>  \n> -\tV4L2BufferCache *cache_;\n> +\tstd::unique_ptr<V4L2BufferCache> cache_;\n>  \tstd::map<unsigned int, FrameBuffer *> queuedBuffers_;\n>  \n> -\tEventNotifier *fdBufferNotifier_;\n> +\tstd::unique_ptr<EventNotifier> fdBufferNotifier_;\n>  \n>  \tState state_;\n>  \tstd::optional<unsigned int> firstFrame_;\n> @@ -301,14 +301,14 @@ public:\n>  \tint open();\n>  \tvoid close();\n>  \n> -\tV4L2VideoDevice *output() { return output_; }\n> -\tV4L2VideoDevice *capture() { return capture_; }\n> +\tV4L2VideoDevice *output() { return output_.get(); }\n> +\tV4L2VideoDevice *capture() { return capture_.get(); }\n>  \n>  private:\n>  \tstd::string deviceNode_;\n>  \n> -\tV4L2VideoDevice *output_;\n> -\tV4L2VideoDevice *capture_;\n> +\tstd::unique_ptr<V4L2VideoDevice> output_;\n> +\tstd::unique_ptr<V4L2VideoDevice> capture_;\n>  };\n>  \n>  } /* namespace libcamera */\n> diff --git a/src/apps/qcam/main.cpp b/src/apps/qcam/main.cpp\n> index d0bde14130fb..8c43d43f0dca 100644\n> --- a/src/apps/qcam/main.cpp\n> +++ b/src/apps/qcam/main.cpp\n> @@ -73,7 +73,7 @@ int main(int argc, char **argv)\n>  \tsa.sa_handler = &signalHandler;\n>  \tsigaction(SIGINT, &sa, nullptr);\n>  \n> -\tCameraManager *cm = new libcamera::CameraManager();\n> +\tstd::unique_ptr<CameraManager> cm = std::make_unique<CameraManager>();\n>  \n>  \tret = cm->start();\n>  \tif (ret) {\n> @@ -82,13 +82,12 @@ int main(int argc, char **argv)\n>  \t\treturn EXIT_FAILURE;\n>  \t}\n>  \n> -\tMainWindow *mainWindow = new MainWindow(cm, options);\n> +\tMainWindow *mainWindow = new MainWindow(cm.get(), options);\n>  \tmainWindow->show();\n>  \tret = app.exec();\n>  \tdelete mainWindow;\n>  \n>  \tcm->stop();\n> -\tdelete cm;\n>  \n>  \treturn ret;\n>  }\n> diff --git a/src/apps/qcam/main_window.cpp b/src/apps/qcam/main_window.cpp\n> index 5a88c5aa8457..59c2aa66cb41 100644\n> --- a/src/apps/qcam/main_window.cpp\n> +++ b/src/apps/qcam/main_window.cpp\n> @@ -87,8 +87,8 @@ private:\n>  };\n>  \n>  MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options)\n> -\t: saveRaw_(nullptr), options_(options), cm_(cm), allocator_(nullptr),\n> -\t  isCapturing_(false), captureRaw_(false)\n> +\t: saveRaw_(nullptr), options_(options), cm_(cm), isCapturing_(false),\n> +\t  captureRaw_(false)\n>  {\n>  \tint ret;\n>  \n> @@ -450,7 +450,7 @@ int MainWindow::startCapture()\n>  \t\tsaveRaw_->setEnabled(config_->size() == 2);\n>  \n>  \t/* Allocate and map buffers. */\n> -\tallocator_ = new FrameBufferAllocator(camera_);\n> +\tallocator_ = std::make_unique<FrameBufferAllocator>(camera_);\n>  \tfor (StreamConfiguration &config : *config_) {\n>  \t\tStream *stream = config.stream();\n>  \n> @@ -531,8 +531,7 @@ error:\n>  \n>  \tfreeBuffers_.clear();\n>  \n> -\tdelete allocator_;\n> -\tallocator_ = nullptr;\n> +\tallocator_.reset();\n>  \n>  \treturn ret;\n>  }\n> @@ -564,7 +563,7 @@ void MainWindow::stopCapture()\n>  \trequests_.clear();\n>  \tfreeQueue_.clear();\n>  \n> -\tdelete allocator_;\n> +\tallocator_.reset();\n>  \n>  \tisCapturing_ = false;\n>  \n> diff --git a/src/apps/qcam/main_window.h b/src/apps/qcam/main_window.h\n> index 81fcf915ade5..20d369ad2318 100644\n> --- a/src/apps/qcam/main_window.h\n> +++ b/src/apps/qcam/main_window.h\n> @@ -109,7 +109,7 @@ private:\n>  \t/* Camera manager, camera, configuration and buffers */\n>  \tlibcamera::CameraManager *cm_;\n>  \tstd::shared_ptr<libcamera::Camera> camera_;\n> -\tlibcamera::FrameBufferAllocator *allocator_;\n> +\tstd::unique_ptr<libcamera::FrameBufferAllocator> allocator_;\n>  \n>  \tstd::unique_ptr<libcamera::CameraConfiguration> config_;\n>  \tstd::map<libcamera::FrameBuffer *, std::unique_ptr<Image>> mappedBuffers_;\n> diff --git a/src/libcamera/device_enumerator_udev.cpp b/src/libcamera/device_enumerator_udev.cpp\n> index 3195dd06e2fc..8b9376ca6ac4 100644\n> --- a/src/libcamera/device_enumerator_udev.cpp\n> +++ b/src/libcamera/device_enumerator_udev.cpp\n> @@ -28,14 +28,12 @@ namespace libcamera {\n>  LOG_DECLARE_CATEGORY(DeviceEnumerator)\n>  \n>  DeviceEnumeratorUdev::DeviceEnumeratorUdev()\n> -\t: udev_(nullptr), monitor_(nullptr), notifier_(nullptr)\n> +\t: udev_(nullptr), monitor_(nullptr)\n>  {\n>  }\n>  \n>  DeviceEnumeratorUdev::~DeviceEnumeratorUdev()\n>  {\n> -\tdelete notifier_;\n> -\n>  \tif (monitor_)\n>  \t\tudev_monitor_unref(monitor_);\n>  \tif (udev_)\n> @@ -212,7 +210,7 @@ done:\n>  \t\treturn ret;\n>  \n>  \tint fd = udev_monitor_get_fd(monitor_);\n> -\tnotifier_ = new EventNotifier(fd, EventNotifier::Read);\n> +\tnotifier_ = std::make_unique<EventNotifier>(fd, EventNotifier::Read);\n>  \tnotifier_->activated.connect(this, &DeviceEnumeratorUdev::udevNotify);\n>  \n>  \treturn 0;\n> diff --git a/src/libcamera/ipc_unixsocket.cpp b/src/libcamera/ipc_unixsocket.cpp\n> index 002053e35557..6ec5a5cb6595 100644\n> --- a/src/libcamera/ipc_unixsocket.cpp\n> +++ b/src/libcamera/ipc_unixsocket.cpp\n> @@ -70,7 +70,7 @@ LOG_DEFINE_CATEGORY(IPCUnixSocket)\n>   */\n>  \n>  IPCUnixSocket::IPCUnixSocket()\n> -\t: headerReceived_(false), notifier_(nullptr)\n> +\t: headerReceived_(false)\n>  {\n>  }\n>  \n> @@ -130,7 +130,7 @@ int IPCUnixSocket::bind(UniqueFD fd)\n>  \t\treturn -EINVAL;\n>  \n>  \tfd_ = std::move(fd);\n> -\tnotifier_ = new EventNotifier(fd_.get(), EventNotifier::Read);\n> +\tnotifier_ = std::make_unique<EventNotifier>(fd_.get(), EventNotifier::Read);\n>  \tnotifier_->activated.connect(this, &IPCUnixSocket::dataNotifier);\n>  \n>  \treturn 0;\n> @@ -146,8 +146,7 @@ void IPCUnixSocket::close()\n>  \tif (!isBound())\n>  \t\treturn;\n>  \n> -\tdelete notifier_;\n> -\tnotifier_ = nullptr;\n> +\tnotifier_.reset();\n>  \n>  \tfd_.reset();\n>  \theaderReceived_ = false;\n> diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp\n> index b49d73b1cb01..d6893210f3d9 100644\n> --- a/src/libcamera/v4l2_device.cpp\n> +++ b/src/libcamera/v4l2_device.cpp\n> @@ -123,7 +123,8 @@ int V4L2Device::setFd(UniqueFD fd)\n>  \n>  \tfd_ = std::move(fd);\n>  \n> -\tfdEventNotifier_ = new EventNotifier(fd_.get(), EventNotifier::Exception);\n> +\tfdEventNotifier_ = std::make_unique<EventNotifier>(fd_.get(),\n> +\t\t\t\t\t\t\t   EventNotifier::Exception);\n>  \tfdEventNotifier_->activated.connect(this, &V4L2Device::eventAvailable);\n>  \tfdEventNotifier_->setEnabled(false);\n>  \n> @@ -142,7 +143,7 @@ void V4L2Device::close()\n>  \tif (!isOpen())\n>  \t\treturn;\n>  \n> -\tdelete fdEventNotifier_;\n> +\tfdEventNotifier_.reset();\n>  \n>  \tfd_.reset();\n>  }\n> diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp\n> index d877df29ee6e..ca87598309de 100644\n> --- a/src/libcamera/v4l2_videodevice.cpp\n> +++ b/src/libcamera/v4l2_videodevice.cpp\n> @@ -535,8 +535,7 @@ std::ostream &operator<<(std::ostream &out, const V4L2DeviceFormat &f)\n>   */\n>  V4L2VideoDevice::V4L2VideoDevice(const std::string &deviceNode)\n>  \t: V4L2Device(deviceNode), formatInfo_(nullptr), cache_(nullptr),\n> -\t  fdBufferNotifier_(nullptr), state_(State::Stopped),\n> -\t  watchdogDuration_(0.0)\n> +\t  state_(State::Stopped), watchdogDuration_(0.0)\n>  {\n>  \t/*\n>  \t * We default to an MMAP based CAPTURE video device, however this will\n> @@ -626,7 +625,7 @@ int V4L2VideoDevice::open()\n>  \t\treturn -EINVAL;\n>  \t}\n>  \n> -\tfdBufferNotifier_ = new EventNotifier(fd(), notifierType);\n> +\tfdBufferNotifier_ = std::make_unique<EventNotifier>(fd(), notifierType);\n>  \tfdBufferNotifier_->activated.connect(this, &V4L2VideoDevice::bufferAvailable);\n>  \tfdBufferNotifier_->setEnabled(false);\n>  \n> @@ -715,7 +714,7 @@ int V4L2VideoDevice::open(SharedFD handle, enum v4l2_buf_type type)\n>  \t\treturn -EINVAL;\n>  \t}\n>  \n> -\tfdBufferNotifier_ = new EventNotifier(fd(), notifierType);\n> +\tfdBufferNotifier_ = std::make_unique<EventNotifier>(fd(), notifierType);\n>  \tfdBufferNotifier_->activated.connect(this, &V4L2VideoDevice::bufferAvailable);\n>  \tfdBufferNotifier_->setEnabled(false);\n>  \n> @@ -760,7 +759,7 @@ void V4L2VideoDevice::close()\n>  \t\treturn;\n>  \n>  \treleaseBuffers();\n> -\tdelete fdBufferNotifier_;\n> +\tfdBufferNotifier_.reset();\n>  \n>  \tformatInfo_ = nullptr;\n>  \n> @@ -1374,7 +1373,7 @@ int V4L2VideoDevice::allocateBuffers(unsigned int count,\n>  \tif (ret < 0)\n>  \t\treturn ret;\n>  \n> -\tcache_ = new V4L2BufferCache(*buffers);\n> +\tcache_ = std::make_unique<V4L2BufferCache>(*buffers);\n>  \tmemoryType_ = V4L2_MEMORY_MMAP;\n>  \n>  \treturn ret;\n> @@ -1599,7 +1598,7 @@ int V4L2VideoDevice::importBuffers(unsigned int count)\n>  \tif (ret)\n>  \t\treturn ret;\n>  \n> -\tcache_ = new V4L2BufferCache(count);\n> +\tcache_ = std::make_unique<V4L2BufferCache>(count);\n>  \n>  \tLOG(V4L2, Debug) << \"Prepared to import \" << count << \" buffers\";\n>  \n> @@ -1621,8 +1620,7 @@ int V4L2VideoDevice::releaseBuffers()\n>  \n>  \tLOG(V4L2, Debug) << \"Releasing buffers\";\n>  \n> -\tdelete cache_;\n> -\tcache_ = nullptr;\n> +\tcache_.reset();\n>  \n>  \treturn requestBuffers(0, memoryType_);\n>  }\n> @@ -2197,14 +2195,12 @@ V4L2PixelFormat V4L2VideoDevice::toV4L2PixelFormat(const PixelFormat &pixelForma\n>  V4L2M2MDevice::V4L2M2MDevice(const std::string &deviceNode)\n>  \t: deviceNode_(deviceNode)\n>  {\n> -\toutput_ = new V4L2VideoDevice(deviceNode);\n> -\tcapture_ = new V4L2VideoDevice(deviceNode);\n> +\toutput_ = std::make_unique<V4L2VideoDevice>(deviceNode);\n> +\tcapture_ = std::make_unique<V4L2VideoDevice>(deviceNode);\n>  }\n>  \n>  V4L2M2MDevice::~V4L2M2MDevice()\n>  {\n> -\tdelete capture_;\n> -\tdelete output_;\n>  }\n>  \n>  /**\n> diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp\n> index 94d138cd5710..412ab4ea678e 100644\n> --- a/src/v4l2/v4l2_camera.cpp\n> +++ b/src/v4l2/v4l2_camera.cpp\n> @@ -20,7 +20,7 @@ LOG_DECLARE_CATEGORY(V4L2Compat)\n>  \n>  V4L2Camera::V4L2Camera(std::shared_ptr<Camera> camera)\n>  \t: camera_(camera), controls_(controls::controls), isRunning_(false),\n> -\t  bufferAllocator_(nullptr), efd_(-1), bufferAvailableCount_(0)\n> +\t  efd_(-1), bufferAvailableCount_(0)\n>  {\n>  \tcamera_->requestCompleted.connect(this, &V4L2Camera::requestComplete);\n>  }\n> @@ -43,7 +43,7 @@ int V4L2Camera::open(StreamConfiguration *streamConfig)\n>  \t\treturn -EINVAL;\n>  \t}\n>  \n> -\tbufferAllocator_ = new FrameBufferAllocator(camera_);\n> +\tbufferAllocator_ = std::make_unique<FrameBufferAllocator>(camera_);\n>  \n>  \t*streamConfig = config_->at(0);\n>  \treturn 0;\n> @@ -53,8 +53,7 @@ void V4L2Camera::close()\n>  {\n>  \trequestPool_.clear();\n>  \n> -\tdelete bufferAllocator_;\n> -\tbufferAllocator_ = nullptr;\n> +\tbufferAllocator_.reset();\n>  \n>  \tcamera_->release();\n>  }\n> diff --git a/src/v4l2/v4l2_camera.h b/src/v4l2/v4l2_camera.h\n> index 9bd161b909de..3d09ae7d6057 100644\n> --- a/src/v4l2/v4l2_camera.h\n> +++ b/src/v4l2/v4l2_camera.h\n> @@ -80,7 +80,7 @@ private:\n>  \tbool isRunning_;\n>  \n>  \tlibcamera::Mutex bufferLock_;\n> -\tlibcamera::FrameBufferAllocator *bufferAllocator_;\n> +\tstd::unique_ptr<libcamera::FrameBufferAllocator> bufferAllocator_;\n>  \n>  \tstd::vector<std::unique_ptr<libcamera::Request>> requestPool_;\n>  \n> diff --git a/src/v4l2/v4l2_compat_manager.cpp b/src/v4l2/v4l2_compat_manager.cpp\n> index f53fb300dde8..a92f2e2944fc 100644\n> --- a/src/v4l2/v4l2_compat_manager.cpp\n> +++ b/src/v4l2/v4l2_compat_manager.cpp\n> @@ -54,25 +54,21 @@ V4L2CompatManager::~V4L2CompatManager()\n>  {\n>  \tfiles_.clear();\n>  \tmmaps_.clear();\n> +\tproxies_.clear();\n>  \n> -\tif (cm_) {\n> -\t\tproxies_.clear();\n> +\tif (cm_)\n>  \t\tcm_->stop();\n> -\t\tdelete cm_;\n> -\t\tcm_ = nullptr;\n> -\t}\n>  }\n>  \n>  int V4L2CompatManager::start()\n>  {\n> -\tcm_ = new CameraManager();\n> +\tcm_ = std::make_unique<CameraManager>();\n>  \n>  \tint ret = cm_->start();\n>  \tif (ret) {\n>  \t\tLOG(V4L2Compat, Error) << \"Failed to start camera manager: \"\n>  \t\t\t\t       << strerror(-ret);\n> -\t\tdelete cm_;\n> -\t\tcm_ = nullptr;\n> +\t\tcm_.reset();\n>  \t\treturn ret;\n>  \t}\n>  \n> @@ -83,10 +79,8 @@ int V4L2CompatManager::start()\n>  \t * created here to wrap a camera device.\n>  \t */\n>  \tauto cameras = cm_->cameras();\n> -\tfor (auto [index, camera] : utils::enumerate(cameras)) {\n> -\t\tV4L2CameraProxy *proxy = new V4L2CameraProxy(index, camera);\n> -\t\tproxies_.emplace_back(proxy);\n> -\t}\n> +\tfor (auto [index, camera] : utils::enumerate(cameras))\n> +\t\tproxies_.emplace_back(std::make_unique<V4L2CameraProxy>(index, camera));\n>  \n>  \treturn 0;\n>  }\n> diff --git a/src/v4l2/v4l2_compat_manager.h b/src/v4l2/v4l2_compat_manager.h\n> index f7c6f1228282..13673d604a63 100644\n> --- a/src/v4l2/v4l2_compat_manager.h\n> +++ b/src/v4l2/v4l2_compat_manager.h\n> @@ -61,7 +61,7 @@ private:\n>  \n>  \tFileOperations fops_;\n>  \n> -\tlibcamera::CameraManager *cm_;\n> +\tstd::unique_ptr<libcamera::CameraManager> cm_;\n>  \n>  \tstd::vector<std::unique_ptr<V4L2CameraProxy>> proxies_;\n>  \tstd::map<int, std::shared_ptr<V4L2CameraFile>> files_;","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 AF942BDCBD\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed,  8 Apr 2026 18:15:44 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id CE51162E39;\n\tWed,  8 Apr 2026 20:15:43 +0200 (CEST)","from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.129.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3A8B862CE6\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  8 Apr 2026 20:15:42 +0200 (CEST)","from mail-wr1-f72.google.com (mail-wr1-f72.google.com\n\t[209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-139-fpW_mPjyM6yfCmrMhWfj6g-1; Wed, 08 Apr 2026 14:15:39 -0400","by mail-wr1-f72.google.com with SMTP id\n\tffacd0b85a97d-43d5651fedaso14162f8f.2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 08 Apr 2026 11:15:39 -0700 (PDT)","from mzamazal-thinkpadp1gen7.tpbc.csb\n\t(ip-77-48-47-2.net.vodafone.cz. [77.48.47.2])\n\tby smtp.gmail.com with ESMTPSA id\n\tffacd0b85a97d-43d1e2a7223sm56588008f8f.5.2026.04.08.11.15.36\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tWed, 08 Apr 2026 11:15:36 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"PD4SrdjF\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1775672141;\n\th=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n\tto:to:cc:cc:mime-version:mime-version:content-type:content-type:\n\tin-reply-to:in-reply-to:references:references;\n\tbh=aPBw8N+s+pU4JxmTT3snjmI6S7ExiHDkLFIKgtceZNc=;\n\tb=PD4SrdjFOTA5V8dNL/BFeVtZ8Fx7NNW1Wcqo5AV8IjUEoGKmJamzfPEmKG48u78hQjZEZR\n\t9ELKRMElWbIlLrJRDyBAygV/5zJqVarZ0stSQxeACdYtRg51JknvoZpsNcUPXJQYdMt8qT\n\tFJzLnk13yiJLvyJNsgn3zceY2FpYvHo=","X-MC-Unique":"fpW_mPjyM6yfCmrMhWfj6g-1","X-Mimecast-MFC-AGG-ID":"fpW_mPjyM6yfCmrMhWfj6g_1775672139","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20251104; t=1775672138; x=1776276938;\n\th=mime-version:user-agent:message-id:date:references:in-reply-to\n\t:subject:cc:to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject\n\t:date:message-id:reply-to;\n\tbh=aPBw8N+s+pU4JxmTT3snjmI6S7ExiHDkLFIKgtceZNc=;\n\tb=iVbchL66gTN7ovDbiBUY16K+w/JQvNcFV74DMF5yJVyKexS1d13B0Gs8mkvUrgEB/D\n\tU2ReAFySHEflr4j/pSob0pBBNYHBLU4voDCSHMQXkTxChdPvVCYDH3olOIzxO+ug42UE\n\tFQcR9jd35980lgJUyu0tYa8PJuCqhDrhNoFnGB1XS79Ek7oYwGbN7/GMoIs64mdM2SUm\n\tnfBfEWyK6paKSVMoCj01m1GM9a7hKHhqjinJnqtfqyEK8S5UZ4xPjGFkOK+ylvaDBCcc\n\tXkdy3t8OvD8YYKlyqaTw6xo6E3bBqJx/z0VdU3dEYqFBUUGt+d5Jl0XydZx73c+dgWk1\n\t3Zog==","X-Gm-Message-State":"AOJu0YzeAuoRypYXMq6Ir1gb8/w/62igLKMxNOnmfCa2htVo0RL4L+Ej\n\turwmf3qdRvBSfAcr4yNxWh3JVl599pTSzFaGPgKG3aZa3ZOvsJy53VpRjf2M/mzXU/slO9SNmq9\n\tFVsYRv7GKnA/nAElSwFXxR9JJP0r7Evt3WM6pD5qvfCtyHgcagyFMu8g4YJAdqwz4r5ujI7mQYO\n\ttRzdCXsIlXVXg2S0+So5LOd9+Pm1umu0Sd4K0I0a1g2OpMuOx8IWFYZo2mJfw=","X-Gm-Gg":"AeBDievwp/x32+Xla1lYz7C3iWxuJ1S5NBXKjPbalkL9V5dU64MP2z+49ZYCygr7JCa\n\t0X1c5nSyO01Dwf8PIqqJ5xK4E1ApOtH4AI1mB5LfgaVoHlG966RcvHUS61bFugpp0JhLCqCc+XI\n\tqH8C3JF/i48EYABAJ03bgPSDKV0ZKtcSjbVaxUTSuh1GKIYHmcMxzPbOglSVhGxgJ5s8asZTse2\n\tXLFTtbiHF0Ne6A3VSDA5b45D3npnK38ZZZx7+mRO1ZDycn44SZwVrmVuyR2FBQFTHrDVkGeDl2C\n\tuhL84IrnND9h5C2BjM72tpM69YXJx4jSnn82TqEp7bR3gZ9Tpy4V9irkOlqmty6Egc4pZccZbYx\n\tINg9OPef6eJP6bdtTwvRCV7HOYF2q+foA9ysv5MN+DnGaNjEZgQoj+1deC+7gg1WmiZHLB/JiBV\n\t0=","X-Received":["by 2002:a05:6000:26cf:b0:43b:9060:8829 with SMTP id\n\tffacd0b85a97d-43d5a0fa3b4mr492117f8f.10.1775672138158; \n\tWed, 08 Apr 2026 11:15:38 -0700 (PDT)","by 2002:a05:6000:26cf:b0:43b:9060:8829 with SMTP id\n\tffacd0b85a97d-43d5a0fa3b4mr492061f8f.10.1775672137492; \n\tWed, 08 Apr 2026 11:15:37 -0700 (PDT)"],"From":"Milan Zamazal <mzamazal@redhat.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH v2 03/42] libcamera: Replace plain pointers with\n\tstd::unique<>","In-Reply-To":"<20260407153427.1825999-4-laurent.pinchart@ideasonboard.com>\n\t(Laurent Pinchart's message of \"Tue, 7 Apr 2026 18:33:48 +0300\")","References":"<20260407153427.1825999-1-laurent.pinchart@ideasonboard.com>\n\t<20260407153427.1825999-4-laurent.pinchart@ideasonboard.com>","Date":"Wed, 08 Apr 2026 20:15:35 +0200","Message-ID":"<85cy099v3s.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","User-Agent":"Gnus/5.13 (Gnus v5.13)","MIME-Version":"1.0","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"2NFQsZAP888z1r-HWmpudASVzZwa4sIAoWfnU5cyM1g_1775672139","X-Mimecast-Originator":"redhat.com","Content-Type":"text/plain","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>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":38627,"web_url":"https://patchwork.libcamera.org/comment/38627/","msgid":"<20260423190901.GA3086691@killaraus.ideasonboard.com>","date":"2026-04-23T19:09:01","subject":"Re: [PATCH v2 03/42] libcamera: Replace plain pointers with\n\tstd::unique<>","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Thu, Apr 23, 2026 at 01:19:08PM +0100, Isaac Scott wrote:\n> Hi Laurent,\n> \n> Thank you for the patch!\n> \n> Quoting Laurent Pinchart (2026-04-07 16:33:48)\n> > libcamera uses std::unique_ptr<> to simplify life time management of\n> > objects and avoid leaks. For historical reasons there are a fair number\n> > of plain pointers with manual memory management. Replace them with\n> > std::unique_ptr<> when the conversion is simple.\n> > \n> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > ---\n> >  .../guides/application-developer.rst          |  5 +++--\n> >  .../internal/device_enumerator_udev.h         |  2 +-\n> >  include/libcamera/internal/ipc_unixsocket.h   |  3 ++-\n> >  include/libcamera/internal/v4l2_device.h      |  2 +-\n> >  include/libcamera/internal/v4l2_videodevice.h | 12 +++++-----\n> >  src/apps/qcam/main.cpp                        |  5 ++---\n> >  src/apps/qcam/main_window.cpp                 | 11 +++++-----\n> >  src/apps/qcam/main_window.h                   |  2 +-\n> >  src/libcamera/device_enumerator_udev.cpp      |  6 ++---\n> >  src/libcamera/ipc_unixsocket.cpp              |  7 +++---\n> >  src/libcamera/v4l2_device.cpp                 |  5 +++--\n> >  src/libcamera/v4l2_videodevice.cpp            | 22 ++++++++-----------\n> >  src/v4l2/v4l2_camera.cpp                      |  7 +++---\n> >  src/v4l2/v4l2_camera.h                        |  2 +-\n> >  src/v4l2/v4l2_compat_manager.cpp              | 18 +++++----------\n> >  src/v4l2/v4l2_compat_manager.h                |  2 +-\n> >  16 files changed, 49 insertions(+), 62 deletions(-)\n> > \n> > diff --git a/Documentation/guides/application-developer.rst b/Documentation/guides/application-developer.rst\n> > index 918077af1d22..fd91cc503568 100644\n> > --- a/Documentation/guides/application-developer.rst\n> > +++ b/Documentation/guides/application-developer.rst\n> > @@ -279,7 +279,8 @@ as the parameter of the ``FrameBufferAllocator::buffers()`` function.\n> >  \n> >  .. code:: cpp\n> >  \n> > -   FrameBufferAllocator *allocator = new FrameBufferAllocator(camera);\n> > +   std::unique_ptr<FrameBufferAllocator> allocator =\n> > +       std::make_unique<FrameBufferAllocator>(camera);\n> >  \n> >     for (StreamConfiguration &cfg : *config) {\n> >         int ret = allocator->allocate(cfg.stream());\n> > @@ -539,7 +540,7 @@ uses, so needs to do the following:\n> >  \n> >     camera->stop();\n> >     allocator->free(stream);\n> > -   delete allocator;\n> > +   allocator.reset();\n> >     camera->release();\n> >     camera.reset();\n> >     cm->stop();\n> > diff --git a/include/libcamera/internal/device_enumerator_udev.h b/include/libcamera/internal/device_enumerator_udev.h\n> > index 0bf78b551e75..1ce988ab84d1 100644\n> > --- a/include/libcamera/internal/device_enumerator_udev.h\n> > +++ b/include/libcamera/internal/device_enumerator_udev.h\n> > @@ -69,7 +69,7 @@ private:\n> >  \n> >         struct udev *udev_;\n> >         struct udev_monitor *monitor_;\n> > -       EventNotifier *notifier_;\n> > +       std::unique_ptr<EventNotifier> notifier_;\n> >  \n> >         std::set<dev_t> orphans_;\n> >         std::unordered_set<dev_t> devices_;\n> > diff --git a/include/libcamera/internal/ipc_unixsocket.h b/include/libcamera/internal/ipc_unixsocket.h\n> > index 48bb7a9422b5..57614fa3f0c7 100644\n> > --- a/include/libcamera/internal/ipc_unixsocket.h\n> > +++ b/include/libcamera/internal/ipc_unixsocket.h\n> > @@ -7,6 +7,7 @@\n> >  \n> >  #pragma once\n> >  \n> > +#include <memory>\n> >  #include <stdint.h>\n> >  #include <sys/types.h>\n> >  #include <vector>\n> > @@ -53,7 +54,7 @@ private:\n> >         UniqueFD fd_;\n> >         bool headerReceived_;\n> >         struct Header header_;\n> > -       EventNotifier *notifier_;\n> > +       std::unique_ptr<EventNotifier> notifier_;\n> >  };\n> >  \n> >  } /* namespace libcamera */\n> > diff --git a/include/libcamera/internal/v4l2_device.h b/include/libcamera/internal/v4l2_device.h\n> > index dbbd118abd00..8c4c59bf7773 100644\n> > --- a/include/libcamera/internal/v4l2_device.h\n> > +++ b/include/libcamera/internal/v4l2_device.h\n> > @@ -89,7 +89,7 @@ private:\n> >         std::string deviceNode_;\n> >         UniqueFD fd_;\n> >  \n> > -       EventNotifier *fdEventNotifier_;\n> > +       std::unique_ptr<EventNotifier> fdEventNotifier_;\n> >         bool frameStartEnabled_;\n> >  };\n> >  \n> > diff --git a/include/libcamera/internal/v4l2_videodevice.h b/include/libcamera/internal/v4l2_videodevice.h\n> > index 57db0036db6b..10367e4e178a 100644\n> > --- a/include/libcamera/internal/v4l2_videodevice.h\n> > +++ b/include/libcamera/internal/v4l2_videodevice.h\n> > @@ -280,10 +280,10 @@ private:\n> >         enum v4l2_buf_type bufferType_;\n> >         enum v4l2_memory memoryType_;\n> >  \n> > -       V4L2BufferCache *cache_;\n> > +       std::unique_ptr<V4L2BufferCache> cache_;\n> >         std::map<unsigned int, FrameBuffer *> queuedBuffers_;\n> >  \n> > -       EventNotifier *fdBufferNotifier_;\n> > +       std::unique_ptr<EventNotifier> fdBufferNotifier_;\n> >  \n> >         State state_;\n> >         std::optional<unsigned int> firstFrame_;\n> > @@ -301,14 +301,14 @@ public:\n> >         int open();\n> >         void close();\n> >  \n> > -       V4L2VideoDevice *output() { return output_; }\n> > -       V4L2VideoDevice *capture() { return capture_; }\n> > +       V4L2VideoDevice *output() { return output_.get(); }\n> > +       V4L2VideoDevice *capture() { return capture_.get(); }\n> >  \n> >  private:\n> >         std::string deviceNode_;\n> >  \n> > -       V4L2VideoDevice *output_;\n> > -       V4L2VideoDevice *capture_;\n> > +       std::unique_ptr<V4L2VideoDevice> output_;\n> > +       std::unique_ptr<V4L2VideoDevice> capture_;\n> >  };\n> >  \n> >  } /* namespace libcamera */\n> > diff --git a/src/apps/qcam/main.cpp b/src/apps/qcam/main.cpp\n> > index d0bde14130fb..8c43d43f0dca 100644\n> > --- a/src/apps/qcam/main.cpp\n> > +++ b/src/apps/qcam/main.cpp\n> > @@ -73,7 +73,7 @@ int main(int argc, char **argv)\n> >         sa.sa_handler = &signalHandler;\n> >         sigaction(SIGINT, &sa, nullptr);\n> >  \n> > -       CameraManager *cm = new libcamera::CameraManager();\n> > +       std::unique_ptr<CameraManager> cm = std::make_unique<CameraManager>();\n> >  \n> >         ret = cm->start();\n> >         if (ret) {\n> > @@ -82,13 +82,12 @@ int main(int argc, char **argv)\n> >                 return EXIT_FAILURE;\n> >         }\n> >  \n> > -       MainWindow *mainWindow = new MainWindow(cm, options);\n> > +       MainWindow *mainWindow = new MainWindow(cm.get(), options);\n> >         mainWindow->show();\n> >         ret = app.exec();\n> >         delete mainWindow;\n> >  \n> >         cm->stop();\n> > -       delete cm;\n> >  \n> >         return ret;\n> >  }\n> > diff --git a/src/apps/qcam/main_window.cpp b/src/apps/qcam/main_window.cpp\n> > index 5a88c5aa8457..59c2aa66cb41 100644\n> > --- a/src/apps/qcam/main_window.cpp\n> > +++ b/src/apps/qcam/main_window.cpp\n> > @@ -87,8 +87,8 @@ private:\n> >  };\n> >  \n> >  MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options)\n> > -       : saveRaw_(nullptr), options_(options), cm_(cm), allocator_(nullptr),\n> > -         isCapturing_(false), captureRaw_(false)\n> > +       : saveRaw_(nullptr), options_(options), cm_(cm), isCapturing_(false),\n> > +         captureRaw_(false)\n> \n> Is it OK to remove the allocator_ initialisation here? Perhaps by\n> default it will be nullptr because its now a smart pointer, or at least\n> \"empty\"...\n\nThat's right, the std::unique_ptr<> default constructor initializes it\nto a null pointer.\n\n> >  {\n> >         int ret;\n> >  \n> > @@ -450,7 +450,7 @@ int MainWindow::startCapture()\n> >                 saveRaw_->setEnabled(config_->size() == 2);\n> >  \n> >         /* Allocate and map buffers. */\n> > -       allocator_ = new FrameBufferAllocator(camera_);\n> > +       allocator_ = std::make_unique<FrameBufferAllocator>(camera_);\n> \n> I guess we initialise it here, so it's probably fine.\n> \n> Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>\n> \n> >         for (StreamConfiguration &config : *config_) {\n> >                 Stream *stream = config.stream();\n> >  \n> > @@ -531,8 +531,7 @@ error:\n> >  \n> >         freeBuffers_.clear();\n> >  \n> > -       delete allocator_;\n> > -       allocator_ = nullptr;\n> > +       allocator_.reset();\n> >  \n> >         return ret;\n> >  }\n> > @@ -564,7 +563,7 @@ void MainWindow::stopCapture()\n> >         requests_.clear();\n> >         freeQueue_.clear();\n> >  \n> > -       delete allocator_;\n> > +       allocator_.reset();\n> >  \n> >         isCapturing_ = false;\n> >  \n> > diff --git a/src/apps/qcam/main_window.h b/src/apps/qcam/main_window.h\n> > index 81fcf915ade5..20d369ad2318 100644\n> > --- a/src/apps/qcam/main_window.h\n> > +++ b/src/apps/qcam/main_window.h\n> > @@ -109,7 +109,7 @@ private:\n> >         /* Camera manager, camera, configuration and buffers */\n> >         libcamera::CameraManager *cm_;\n> >         std::shared_ptr<libcamera::Camera> camera_;\n> > -       libcamera::FrameBufferAllocator *allocator_;\n> > +       std::unique_ptr<libcamera::FrameBufferAllocator> allocator_;\n> >  \n> >         std::unique_ptr<libcamera::CameraConfiguration> config_;\n> >         std::map<libcamera::FrameBuffer *, std::unique_ptr<Image>> mappedBuffers_;\n> > diff --git a/src/libcamera/device_enumerator_udev.cpp b/src/libcamera/device_enumerator_udev.cpp\n> > index 3195dd06e2fc..8b9376ca6ac4 100644\n> > --- a/src/libcamera/device_enumerator_udev.cpp\n> > +++ b/src/libcamera/device_enumerator_udev.cpp\n> > @@ -28,14 +28,12 @@ namespace libcamera {\n> >  LOG_DECLARE_CATEGORY(DeviceEnumerator)\n> >  \n> >  DeviceEnumeratorUdev::DeviceEnumeratorUdev()\n> > -       : udev_(nullptr), monitor_(nullptr), notifier_(nullptr)\n> > +       : udev_(nullptr), monitor_(nullptr)\n> >  {\n> >  }\n> >  \n> >  DeviceEnumeratorUdev::~DeviceEnumeratorUdev()\n> >  {\n> > -       delete notifier_;\n> > -\n> >         if (monitor_)\n> >                 udev_monitor_unref(monitor_);\n> >         if (udev_)\n> > @@ -212,7 +210,7 @@ done:\n> >                 return ret;\n> >  \n> >         int fd = udev_monitor_get_fd(monitor_);\n> > -       notifier_ = new EventNotifier(fd, EventNotifier::Read);\n> > +       notifier_ = std::make_unique<EventNotifier>(fd, EventNotifier::Read);\n> >         notifier_->activated.connect(this, &DeviceEnumeratorUdev::udevNotify);\n> >  \n> >         return 0;\n> > diff --git a/src/libcamera/ipc_unixsocket.cpp b/src/libcamera/ipc_unixsocket.cpp\n> > index 002053e35557..6ec5a5cb6595 100644\n> > --- a/src/libcamera/ipc_unixsocket.cpp\n> > +++ b/src/libcamera/ipc_unixsocket.cpp\n> > @@ -70,7 +70,7 @@ LOG_DEFINE_CATEGORY(IPCUnixSocket)\n> >   */\n> >  \n> >  IPCUnixSocket::IPCUnixSocket()\n> > -       : headerReceived_(false), notifier_(nullptr)\n> > +       : headerReceived_(false)\n> >  {\n> >  }\n> >  \n> > @@ -130,7 +130,7 @@ int IPCUnixSocket::bind(UniqueFD fd)\n> >                 return -EINVAL;\n> >  \n> >         fd_ = std::move(fd);\n> > -       notifier_ = new EventNotifier(fd_.get(), EventNotifier::Read);\n> > +       notifier_ = std::make_unique<EventNotifier>(fd_.get(), EventNotifier::Read);\n> >         notifier_->activated.connect(this, &IPCUnixSocket::dataNotifier);\n> >  \n> >         return 0;\n> > @@ -146,8 +146,7 @@ void IPCUnixSocket::close()\n> >         if (!isBound())\n> >                 return;\n> >  \n> > -       delete notifier_;\n> > -       notifier_ = nullptr;\n> > +       notifier_.reset();\n> >  \n> >         fd_.reset();\n> >         headerReceived_ = false;\n> > diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp\n> > index b49d73b1cb01..d6893210f3d9 100644\n> > --- a/src/libcamera/v4l2_device.cpp\n> > +++ b/src/libcamera/v4l2_device.cpp\n> > @@ -123,7 +123,8 @@ int V4L2Device::setFd(UniqueFD fd)\n> >  \n> >         fd_ = std::move(fd);\n> >  \n> > -       fdEventNotifier_ = new EventNotifier(fd_.get(), EventNotifier::Exception);\n> > +       fdEventNotifier_ = std::make_unique<EventNotifier>(fd_.get(),\n> > +                                                          EventNotifier::Exception);\n> >         fdEventNotifier_->activated.connect(this, &V4L2Device::eventAvailable);\n> >         fdEventNotifier_->setEnabled(false);\n> >  \n> > @@ -142,7 +143,7 @@ void V4L2Device::close()\n> >         if (!isOpen())\n> >                 return;\n> >  \n> > -       delete fdEventNotifier_;\n> > +       fdEventNotifier_.reset();\n> >  \n> >         fd_.reset();\n> >  }\n> > diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp\n> > index d877df29ee6e..ca87598309de 100644\n> > --- a/src/libcamera/v4l2_videodevice.cpp\n> > +++ b/src/libcamera/v4l2_videodevice.cpp\n> > @@ -535,8 +535,7 @@ std::ostream &operator<<(std::ostream &out, const V4L2DeviceFormat &f)\n> >   */\n> >  V4L2VideoDevice::V4L2VideoDevice(const std::string &deviceNode)\n> >         : V4L2Device(deviceNode), formatInfo_(nullptr), cache_(nullptr),\n> > -         fdBufferNotifier_(nullptr), state_(State::Stopped),\n> > -         watchdogDuration_(0.0)\n> > +         state_(State::Stopped), watchdogDuration_(0.0)\n> >  {\n> >         /*\n> >          * We default to an MMAP based CAPTURE video device, however this will\n> > @@ -626,7 +625,7 @@ int V4L2VideoDevice::open()\n> >                 return -EINVAL;\n> >         }\n> >  \n> > -       fdBufferNotifier_ = new EventNotifier(fd(), notifierType);\n> > +       fdBufferNotifier_ = std::make_unique<EventNotifier>(fd(), notifierType);\n> >         fdBufferNotifier_->activated.connect(this, &V4L2VideoDevice::bufferAvailable);\n> >         fdBufferNotifier_->setEnabled(false);\n> >  \n> > @@ -715,7 +714,7 @@ int V4L2VideoDevice::open(SharedFD handle, enum v4l2_buf_type type)\n> >                 return -EINVAL;\n> >         }\n> >  \n> > -       fdBufferNotifier_ = new EventNotifier(fd(), notifierType);\n> > +       fdBufferNotifier_ = std::make_unique<EventNotifier>(fd(), notifierType);\n> >         fdBufferNotifier_->activated.connect(this, &V4L2VideoDevice::bufferAvailable);\n> >         fdBufferNotifier_->setEnabled(false);\n> >  \n> > @@ -760,7 +759,7 @@ void V4L2VideoDevice::close()\n> >                 return;\n> >  \n> >         releaseBuffers();\n> > -       delete fdBufferNotifier_;\n> > +       fdBufferNotifier_.reset();\n> >  \n> >         formatInfo_ = nullptr;\n> >  \n> > @@ -1374,7 +1373,7 @@ int V4L2VideoDevice::allocateBuffers(unsigned int count,\n> >         if (ret < 0)\n> >                 return ret;\n> >  \n> > -       cache_ = new V4L2BufferCache(*buffers);\n> > +       cache_ = std::make_unique<V4L2BufferCache>(*buffers);\n> >         memoryType_ = V4L2_MEMORY_MMAP;\n> >  \n> >         return ret;\n> > @@ -1599,7 +1598,7 @@ int V4L2VideoDevice::importBuffers(unsigned int count)\n> >         if (ret)\n> >                 return ret;\n> >  \n> > -       cache_ = new V4L2BufferCache(count);\n> > +       cache_ = std::make_unique<V4L2BufferCache>(count);\n> >  \n> >         LOG(V4L2, Debug) << \"Prepared to import \" << count << \" buffers\";\n> >  \n> > @@ -1621,8 +1620,7 @@ int V4L2VideoDevice::releaseBuffers()\n> >  \n> >         LOG(V4L2, Debug) << \"Releasing buffers\";\n> >  \n> > -       delete cache_;\n> > -       cache_ = nullptr;\n> > +       cache_.reset();\n> >  \n> >         return requestBuffers(0, memoryType_);\n> >  }\n> > @@ -2197,14 +2195,12 @@ V4L2PixelFormat V4L2VideoDevice::toV4L2PixelFormat(const PixelFormat &pixelForma\n> >  V4L2M2MDevice::V4L2M2MDevice(const std::string &deviceNode)\n> >         : deviceNode_(deviceNode)\n> >  {\n> > -       output_ = new V4L2VideoDevice(deviceNode);\n> > -       capture_ = new V4L2VideoDevice(deviceNode);\n> > +       output_ = std::make_unique<V4L2VideoDevice>(deviceNode);\n> > +       capture_ = std::make_unique<V4L2VideoDevice>(deviceNode);\n> >  }\n> >  \n> >  V4L2M2MDevice::~V4L2M2MDevice()\n> >  {\n> > -       delete capture_;\n> > -       delete output_;\n> >  }\n> >  \n> >  /**\n> > diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp\n> > index 94d138cd5710..412ab4ea678e 100644\n> > --- a/src/v4l2/v4l2_camera.cpp\n> > +++ b/src/v4l2/v4l2_camera.cpp\n> > @@ -20,7 +20,7 @@ LOG_DECLARE_CATEGORY(V4L2Compat)\n> >  \n> >  V4L2Camera::V4L2Camera(std::shared_ptr<Camera> camera)\n> >         : camera_(camera), controls_(controls::controls), isRunning_(false),\n> > -         bufferAllocator_(nullptr), efd_(-1), bufferAvailableCount_(0)\n> > +         efd_(-1), bufferAvailableCount_(0)\n> >  {\n> >         camera_->requestCompleted.connect(this, &V4L2Camera::requestComplete);\n> >  }\n> > @@ -43,7 +43,7 @@ int V4L2Camera::open(StreamConfiguration *streamConfig)\n> >                 return -EINVAL;\n> >         }\n> >  \n> > -       bufferAllocator_ = new FrameBufferAllocator(camera_);\n> > +       bufferAllocator_ = std::make_unique<FrameBufferAllocator>(camera_);\n> >  \n> >         *streamConfig = config_->at(0);\n> >         return 0;\n> > @@ -53,8 +53,7 @@ void V4L2Camera::close()\n> >  {\n> >         requestPool_.clear();\n> >  \n> > -       delete bufferAllocator_;\n> > -       bufferAllocator_ = nullptr;\n> > +       bufferAllocator_.reset();\n> >  \n> >         camera_->release();\n> >  }\n> > diff --git a/src/v4l2/v4l2_camera.h b/src/v4l2/v4l2_camera.h\n> > index 9bd161b909de..3d09ae7d6057 100644\n> > --- a/src/v4l2/v4l2_camera.h\n> > +++ b/src/v4l2/v4l2_camera.h\n> > @@ -80,7 +80,7 @@ private:\n> >         bool isRunning_;\n> >  \n> >         libcamera::Mutex bufferLock_;\n> > -       libcamera::FrameBufferAllocator *bufferAllocator_;\n> > +       std::unique_ptr<libcamera::FrameBufferAllocator> bufferAllocator_;\n> >  \n> >         std::vector<std::unique_ptr<libcamera::Request>> requestPool_;\n> >  \n> > diff --git a/src/v4l2/v4l2_compat_manager.cpp b/src/v4l2/v4l2_compat_manager.cpp\n> > index f53fb300dde8..a92f2e2944fc 100644\n> > --- a/src/v4l2/v4l2_compat_manager.cpp\n> > +++ b/src/v4l2/v4l2_compat_manager.cpp\n> > @@ -54,25 +54,21 @@ V4L2CompatManager::~V4L2CompatManager()\n> >  {\n> >         files_.clear();\n> >         mmaps_.clear();\n> > +       proxies_.clear();\n> >  \n> > -       if (cm_) {\n> > -               proxies_.clear();\n> > +       if (cm_)\n> >                 cm_->stop();\n> > -               delete cm_;\n> > -               cm_ = nullptr;\n> > -       }\n> >  }\n> >  \n> >  int V4L2CompatManager::start()\n> >  {\n> > -       cm_ = new CameraManager();\n> > +       cm_ = std::make_unique<CameraManager>();\n> >  \n> >         int ret = cm_->start();\n> >         if (ret) {\n> >                 LOG(V4L2Compat, Error) << \"Failed to start camera manager: \"\n> >                                        << strerror(-ret);\n> > -               delete cm_;\n> > -               cm_ = nullptr;\n> > +               cm_.reset();\n> >                 return ret;\n> >         }\n> >  \n> > @@ -83,10 +79,8 @@ int V4L2CompatManager::start()\n> >          * created here to wrap a camera device.\n> >          */\n> >         auto cameras = cm_->cameras();\n> > -       for (auto [index, camera] : utils::enumerate(cameras)) {\n> > -               V4L2CameraProxy *proxy = new V4L2CameraProxy(index, camera);\n> > -               proxies_.emplace_back(proxy);\n> > -       }\n> > +       for (auto [index, camera] : utils::enumerate(cameras))\n> > +               proxies_.emplace_back(std::make_unique<V4L2CameraProxy>(index, camera));\n> >  \n> >         return 0;\n> >  }\n> > diff --git a/src/v4l2/v4l2_compat_manager.h b/src/v4l2/v4l2_compat_manager.h\n> > index f7c6f1228282..13673d604a63 100644\n> > --- a/src/v4l2/v4l2_compat_manager.h\n> > +++ b/src/v4l2/v4l2_compat_manager.h\n> > @@ -61,7 +61,7 @@ private:\n> >  \n> >         FileOperations fops_;\n> >  \n> > -       libcamera::CameraManager *cm_;\n> > +       std::unique_ptr<libcamera::CameraManager> cm_;\n> >  \n> >         std::vector<std::unique_ptr<V4L2CameraProxy>> proxies_;\n> >         std::map<int, std::shared_ptr<V4L2CameraFile>> files_;","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 C8414BDCB5\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 23 Apr 2026 19:09:05 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 8624362F55;\n\tThu, 23 Apr 2026 21:09:04 +0200 (CEST)","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 C759F62010\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 23 Apr 2026 21:09:02 +0200 (CEST)","from killaraus.ideasonboard.com\n\t(2001-14ba-703d-e500--2a1.rev.dnainternet.fi\n\t[IPv6:2001:14ba:703d:e500::2a1])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 2A752838;\n\tThu, 23 Apr 2026 21:07:23 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"YMBMN2kU\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1776971243;\n\tbh=a3cflG9waE6uFdweNFhHj7yF+juqdztg7PIqHg4LvGU=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=YMBMN2kUEBGlKvnttB/Dpr+2gRzy9KoeRbCYwxFX46FJIZb028IM4LUKw6w1y7yUD\n\t54ILheFdh18K+wbwmtGe6VGHPqrv9Au03ydhhm1aQ8rf7lytZhNHo/7SWln5VtiBX5\n\t7rHLWk6rTI3pilRWq+uzqDs0SH6Jgp7ch4GWLubQ=","Date":"Thu, 23 Apr 2026 22:09:01 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Isaac Scott <isaac.scott@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH v2 03/42] libcamera: Replace plain pointers with\n\tstd::unique<>","Message-ID":"<20260423190901.GA3086691@killaraus.ideasonboard.com>","References":"<20260407153427.1825999-1-laurent.pinchart@ideasonboard.com>\n\t<20260407153427.1825999-4-laurent.pinchart@ideasonboard.com>\n\t<177694674835.41543.6019347532230224266@t16>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<177694674835.41543.6019347532230224266@t16>","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>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":38628,"web_url":"https://patchwork.libcamera.org/comment/38628/","msgid":"<20260423191614.GB3086691@killaraus.ideasonboard.com>","date":"2026-04-23T19:16:14","subject":"Re: [PATCH v2 03/42] libcamera: Replace plain pointers with\n\tstd::unique<>","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Thu, Apr 23, 2026 at 03:59:16PM +0200, Barnabás Pőcze wrote:\n> 2026. 04. 07. 17:33 keltezéssel, Laurent Pinchart írta:\n> > libcamera uses std::unique_ptr<> to simplify life time management of\n> > objects and avoid leaks. For historical reasons there are a fair number\n> > of plain pointers with manual memory management. Replace them with\n> > std::unique_ptr<> when the conversion is simple.\n> > \n> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > ---\n> >   .../guides/application-developer.rst          |  5 +++--\n> >   .../internal/device_enumerator_udev.h         |  2 +-\n> >   include/libcamera/internal/ipc_unixsocket.h   |  3 ++-\n> >   include/libcamera/internal/v4l2_device.h      |  2 +-\n> >   include/libcamera/internal/v4l2_videodevice.h | 12 +++++-----\n> >   src/apps/qcam/main.cpp                        |  5 ++---\n> >   src/apps/qcam/main_window.cpp                 | 11 +++++-----\n> >   src/apps/qcam/main_window.h                   |  2 +-\n> >   src/libcamera/device_enumerator_udev.cpp      |  6 ++---\n> >   src/libcamera/ipc_unixsocket.cpp              |  7 +++---\n> >   src/libcamera/v4l2_device.cpp                 |  5 +++--\n> >   src/libcamera/v4l2_videodevice.cpp            | 22 ++++++++-----------\n> >   src/v4l2/v4l2_camera.cpp                      |  7 +++---\n> >   src/v4l2/v4l2_camera.h                        |  2 +-\n> >   src/v4l2/v4l2_compat_manager.cpp              | 18 +++++----------\n> >   src/v4l2/v4l2_compat_manager.h                |  2 +-\n> >   16 files changed, 49 insertions(+), 62 deletions(-)\n> > \n> > diff --git a/Documentation/guides/application-developer.rst b/Documentation/guides/application-developer.rst\n> > index 918077af1d22..fd91cc503568 100644\n> > --- a/Documentation/guides/application-developer.rst\n> > +++ b/Documentation/guides/application-developer.rst\n> > @@ -279,7 +279,8 @@ as the parameter of the ``FrameBufferAllocator::buffers()`` function.\n> >   \n> >   .. code:: cpp\n> >   \n> > -   FrameBufferAllocator *allocator = new FrameBufferAllocator(camera);\n> > +   std::unique_ptr<FrameBufferAllocator> allocator =\n> > +       std::make_unique<FrameBufferAllocator>(camera);\n> \n> I think `auto allocator = std::make_unique<...>` is just as readable, and shorter.\n> But in any case\n\nYou know how I dislike auto as I find it often hinders readability. In\nthis specific case you're right, the type is clearly visible, at least\nto someone who knows what std::make_unique<> is. I'm fine setting the\nbar there and assuming the reader has this particular knowledge. I'll\nuse auto.\n\n> Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> \n> >   \n> >      for (StreamConfiguration &cfg : *config) {\n> >          int ret = allocator->allocate(cfg.stream());\n> > @@ -539,7 +540,7 @@ uses, so needs to do the following:\n> >   \n> >      camera->stop();\n> >      allocator->free(stream);\n> > -   delete allocator;\n> > +   allocator.reset();\n> >      camera->release();\n> >      camera.reset();\n> >      cm->stop();\n> > diff --git a/include/libcamera/internal/device_enumerator_udev.h b/include/libcamera/internal/device_enumerator_udev.h\n> > index 0bf78b551e75..1ce988ab84d1 100644\n> > --- a/include/libcamera/internal/device_enumerator_udev.h\n> > +++ b/include/libcamera/internal/device_enumerator_udev.h\n> > @@ -69,7 +69,7 @@ private:\n> >   \n> >   \tstruct udev *udev_;\n> >   \tstruct udev_monitor *monitor_;\n> > -\tEventNotifier *notifier_;\n> > +\tstd::unique_ptr<EventNotifier> notifier_;\n> >   \n> >   \tstd::set<dev_t> orphans_;\n> >   \tstd::unordered_set<dev_t> devices_;\n> > diff --git a/include/libcamera/internal/ipc_unixsocket.h b/include/libcamera/internal/ipc_unixsocket.h\n> > index 48bb7a9422b5..57614fa3f0c7 100644\n> > --- a/include/libcamera/internal/ipc_unixsocket.h\n> > +++ b/include/libcamera/internal/ipc_unixsocket.h\n> > @@ -7,6 +7,7 @@\n> >   \n> >   #pragma once\n> >   \n> > +#include <memory>\n> >   #include <stdint.h>\n> >   #include <sys/types.h>\n> >   #include <vector>\n> > @@ -53,7 +54,7 @@ private:\n> >   \tUniqueFD fd_;\n> >   \tbool headerReceived_;\n> >   \tstruct Header header_;\n> > -\tEventNotifier *notifier_;\n> > +\tstd::unique_ptr<EventNotifier> notifier_;\n> >   };\n> >   \n> >   } /* namespace libcamera */\n> > diff --git a/include/libcamera/internal/v4l2_device.h b/include/libcamera/internal/v4l2_device.h\n> > index dbbd118abd00..8c4c59bf7773 100644\n> > --- a/include/libcamera/internal/v4l2_device.h\n> > +++ b/include/libcamera/internal/v4l2_device.h\n> > @@ -89,7 +89,7 @@ private:\n> >   \tstd::string deviceNode_;\n> >   \tUniqueFD fd_;\n> >   \n> > -\tEventNotifier *fdEventNotifier_;\n> > +\tstd::unique_ptr<EventNotifier> fdEventNotifier_;\n> >   \tbool frameStartEnabled_;\n> >   };\n> >   \n> > diff --git a/include/libcamera/internal/v4l2_videodevice.h b/include/libcamera/internal/v4l2_videodevice.h\n> > index 57db0036db6b..10367e4e178a 100644\n> > --- a/include/libcamera/internal/v4l2_videodevice.h\n> > +++ b/include/libcamera/internal/v4l2_videodevice.h\n> > @@ -280,10 +280,10 @@ private:\n> >   \tenum v4l2_buf_type bufferType_;\n> >   \tenum v4l2_memory memoryType_;\n> >   \n> > -\tV4L2BufferCache *cache_;\n> > +\tstd::unique_ptr<V4L2BufferCache> cache_;\n> >   \tstd::map<unsigned int, FrameBuffer *> queuedBuffers_;\n> >   \n> > -\tEventNotifier *fdBufferNotifier_;\n> > +\tstd::unique_ptr<EventNotifier> fdBufferNotifier_;\n> >   \n> >   \tState state_;\n> >   \tstd::optional<unsigned int> firstFrame_;\n> > @@ -301,14 +301,14 @@ public:\n> >   \tint open();\n> >   \tvoid close();\n> >   \n> > -\tV4L2VideoDevice *output() { return output_; }\n> > -\tV4L2VideoDevice *capture() { return capture_; }\n> > +\tV4L2VideoDevice *output() { return output_.get(); }\n> > +\tV4L2VideoDevice *capture() { return capture_.get(); }\n> >   \n> >   private:\n> >   \tstd::string deviceNode_;\n> >   \n> > -\tV4L2VideoDevice *output_;\n> > -\tV4L2VideoDevice *capture_;\n> > +\tstd::unique_ptr<V4L2VideoDevice> output_;\n> > +\tstd::unique_ptr<V4L2VideoDevice> capture_;\n> >   };\n> >   \n> >   } /* namespace libcamera */\n> > diff --git a/src/apps/qcam/main.cpp b/src/apps/qcam/main.cpp\n> > index d0bde14130fb..8c43d43f0dca 100644\n> > --- a/src/apps/qcam/main.cpp\n> > +++ b/src/apps/qcam/main.cpp\n> > @@ -73,7 +73,7 @@ int main(int argc, char **argv)\n> >   \tsa.sa_handler = &signalHandler;\n> >   \tsigaction(SIGINT, &sa, nullptr);\n> >   \n> > -\tCameraManager *cm = new libcamera::CameraManager();\n> > +\tstd::unique_ptr<CameraManager> cm = std::make_unique<CameraManager>();\n> >   \n> >   \tret = cm->start();\n> >   \tif (ret) {\n> > @@ -82,13 +82,12 @@ int main(int argc, char **argv)\n> >   \t\treturn EXIT_FAILURE;\n> >   \t}\n> >   \n> > -\tMainWindow *mainWindow = new MainWindow(cm, options);\n> > +\tMainWindow *mainWindow = new MainWindow(cm.get(), options);\n> >   \tmainWindow->show();\n> >   \tret = app.exec();\n> >   \tdelete mainWindow;\n> >   \n> >   \tcm->stop();\n> > -\tdelete cm;\n> >   \n> >   \treturn ret;\n> >   }\n> > diff --git a/src/apps/qcam/main_window.cpp b/src/apps/qcam/main_window.cpp\n> > index 5a88c5aa8457..59c2aa66cb41 100644\n> > --- a/src/apps/qcam/main_window.cpp\n> > +++ b/src/apps/qcam/main_window.cpp\n> > @@ -87,8 +87,8 @@ private:\n> >   };\n> >   \n> >   MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options)\n> > -\t: saveRaw_(nullptr), options_(options), cm_(cm), allocator_(nullptr),\n> > -\t  isCapturing_(false), captureRaw_(false)\n> > +\t: saveRaw_(nullptr), options_(options), cm_(cm), isCapturing_(false),\n> > +\t  captureRaw_(false)\n> >   {\n> >   \tint ret;\n> >   \n> > @@ -450,7 +450,7 @@ int MainWindow::startCapture()\n> >   \t\tsaveRaw_->setEnabled(config_->size() == 2);\n> >   \n> >   \t/* Allocate and map buffers. */\n> > -\tallocator_ = new FrameBufferAllocator(camera_);\n> > +\tallocator_ = std::make_unique<FrameBufferAllocator>(camera_);\n> >   \tfor (StreamConfiguration &config : *config_) {\n> >   \t\tStream *stream = config.stream();\n> >   \n> > @@ -531,8 +531,7 @@ error:\n> >   \n> >   \tfreeBuffers_.clear();\n> >   \n> > -\tdelete allocator_;\n> > -\tallocator_ = nullptr;\n> > +\tallocator_.reset();\n> >   \n> >   \treturn ret;\n> >   }\n> > @@ -564,7 +563,7 @@ void MainWindow::stopCapture()\n> >   \trequests_.clear();\n> >   \tfreeQueue_.clear();\n> >   \n> > -\tdelete allocator_;\n> > +\tallocator_.reset();\n> >   \n> >   \tisCapturing_ = false;\n> >   \n> > diff --git a/src/apps/qcam/main_window.h b/src/apps/qcam/main_window.h\n> > index 81fcf915ade5..20d369ad2318 100644\n> > --- a/src/apps/qcam/main_window.h\n> > +++ b/src/apps/qcam/main_window.h\n> > @@ -109,7 +109,7 @@ private:\n> >   \t/* Camera manager, camera, configuration and buffers */\n> >   \tlibcamera::CameraManager *cm_;\n> >   \tstd::shared_ptr<libcamera::Camera> camera_;\n> > -\tlibcamera::FrameBufferAllocator *allocator_;\n> > +\tstd::unique_ptr<libcamera::FrameBufferAllocator> allocator_;\n> >   \n> >   \tstd::unique_ptr<libcamera::CameraConfiguration> config_;\n> >   \tstd::map<libcamera::FrameBuffer *, std::unique_ptr<Image>> mappedBuffers_;\n> > diff --git a/src/libcamera/device_enumerator_udev.cpp b/src/libcamera/device_enumerator_udev.cpp\n> > index 3195dd06e2fc..8b9376ca6ac4 100644\n> > --- a/src/libcamera/device_enumerator_udev.cpp\n> > +++ b/src/libcamera/device_enumerator_udev.cpp\n> > @@ -28,14 +28,12 @@ namespace libcamera {\n> >   LOG_DECLARE_CATEGORY(DeviceEnumerator)\n> >   \n> >   DeviceEnumeratorUdev::DeviceEnumeratorUdev()\n> > -\t: udev_(nullptr), monitor_(nullptr), notifier_(nullptr)\n> > +\t: udev_(nullptr), monitor_(nullptr)\n> >   {\n> >   }\n> >   \n> >   DeviceEnumeratorUdev::~DeviceEnumeratorUdev()\n> >   {\n> > -\tdelete notifier_;\n> > -\n> >   \tif (monitor_)\n> >   \t\tudev_monitor_unref(monitor_);\n> >   \tif (udev_)\n> > @@ -212,7 +210,7 @@ done:\n> >   \t\treturn ret;\n> >   \n> >   \tint fd = udev_monitor_get_fd(monitor_);\n> > -\tnotifier_ = new EventNotifier(fd, EventNotifier::Read);\n> > +\tnotifier_ = std::make_unique<EventNotifier>(fd, EventNotifier::Read);\n> >   \tnotifier_->activated.connect(this, &DeviceEnumeratorUdev::udevNotify);\n> >   \n> >   \treturn 0;\n> > diff --git a/src/libcamera/ipc_unixsocket.cpp b/src/libcamera/ipc_unixsocket.cpp\n> > index 002053e35557..6ec5a5cb6595 100644\n> > --- a/src/libcamera/ipc_unixsocket.cpp\n> > +++ b/src/libcamera/ipc_unixsocket.cpp\n> > @@ -70,7 +70,7 @@ LOG_DEFINE_CATEGORY(IPCUnixSocket)\n> >    */\n> >   \n> >   IPCUnixSocket::IPCUnixSocket()\n> > -\t: headerReceived_(false), notifier_(nullptr)\n> > +\t: headerReceived_(false)\n> >   {\n> >   }\n> >   \n> > @@ -130,7 +130,7 @@ int IPCUnixSocket::bind(UniqueFD fd)\n> >   \t\treturn -EINVAL;\n> >   \n> >   \tfd_ = std::move(fd);\n> > -\tnotifier_ = new EventNotifier(fd_.get(), EventNotifier::Read);\n> > +\tnotifier_ = std::make_unique<EventNotifier>(fd_.get(), EventNotifier::Read);\n> >   \tnotifier_->activated.connect(this, &IPCUnixSocket::dataNotifier);\n> >   \n> >   \treturn 0;\n> > @@ -146,8 +146,7 @@ void IPCUnixSocket::close()\n> >   \tif (!isBound())\n> >   \t\treturn;\n> >   \n> > -\tdelete notifier_;\n> > -\tnotifier_ = nullptr;\n> > +\tnotifier_.reset();\n> >   \n> >   \tfd_.reset();\n> >   \theaderReceived_ = false;\n> > diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp\n> > index b49d73b1cb01..d6893210f3d9 100644\n> > --- a/src/libcamera/v4l2_device.cpp\n> > +++ b/src/libcamera/v4l2_device.cpp\n> > @@ -123,7 +123,8 @@ int V4L2Device::setFd(UniqueFD fd)\n> >   \n> >   \tfd_ = std::move(fd);\n> >   \n> > -\tfdEventNotifier_ = new EventNotifier(fd_.get(), EventNotifier::Exception);\n> > +\tfdEventNotifier_ = std::make_unique<EventNotifier>(fd_.get(),\n> > +\t\t\t\t\t\t\t   EventNotifier::Exception);\n> >   \tfdEventNotifier_->activated.connect(this, &V4L2Device::eventAvailable);\n> >   \tfdEventNotifier_->setEnabled(false);\n> >   \n> > @@ -142,7 +143,7 @@ void V4L2Device::close()\n> >   \tif (!isOpen())\n> >   \t\treturn;\n> >   \n> > -\tdelete fdEventNotifier_;\n> > +\tfdEventNotifier_.reset();\n> >   \n> >   \tfd_.reset();\n> >   }\n> > diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp\n> > index d877df29ee6e..ca87598309de 100644\n> > --- a/src/libcamera/v4l2_videodevice.cpp\n> > +++ b/src/libcamera/v4l2_videodevice.cpp\n> > @@ -535,8 +535,7 @@ std::ostream &operator<<(std::ostream &out, const V4L2DeviceFormat &f)\n> >    */\n> >   V4L2VideoDevice::V4L2VideoDevice(const std::string &deviceNode)\n> >   \t: V4L2Device(deviceNode), formatInfo_(nullptr), cache_(nullptr),\n> > -\t  fdBufferNotifier_(nullptr), state_(State::Stopped),\n> > -\t  watchdogDuration_(0.0)\n> > +\t  state_(State::Stopped), watchdogDuration_(0.0)\n> >   {\n> >   \t/*\n> >   \t * We default to an MMAP based CAPTURE video device, however this will\n> > @@ -626,7 +625,7 @@ int V4L2VideoDevice::open()\n> >   \t\treturn -EINVAL;\n> >   \t}\n> >   \n> > -\tfdBufferNotifier_ = new EventNotifier(fd(), notifierType);\n> > +\tfdBufferNotifier_ = std::make_unique<EventNotifier>(fd(), notifierType);\n> >   \tfdBufferNotifier_->activated.connect(this, &V4L2VideoDevice::bufferAvailable);\n> >   \tfdBufferNotifier_->setEnabled(false);\n> >   \n> > @@ -715,7 +714,7 @@ int V4L2VideoDevice::open(SharedFD handle, enum v4l2_buf_type type)\n> >   \t\treturn -EINVAL;\n> >   \t}\n> >   \n> > -\tfdBufferNotifier_ = new EventNotifier(fd(), notifierType);\n> > +\tfdBufferNotifier_ = std::make_unique<EventNotifier>(fd(), notifierType);\n> >   \tfdBufferNotifier_->activated.connect(this, &V4L2VideoDevice::bufferAvailable);\n> >   \tfdBufferNotifier_->setEnabled(false);\n> >   \n> > @@ -760,7 +759,7 @@ void V4L2VideoDevice::close()\n> >   \t\treturn;\n> >   \n> >   \treleaseBuffers();\n> > -\tdelete fdBufferNotifier_;\n> > +\tfdBufferNotifier_.reset();\n> >   \n> >   \tformatInfo_ = nullptr;\n> >   \n> > @@ -1374,7 +1373,7 @@ int V4L2VideoDevice::allocateBuffers(unsigned int count,\n> >   \tif (ret < 0)\n> >   \t\treturn ret;\n> >   \n> > -\tcache_ = new V4L2BufferCache(*buffers);\n> > +\tcache_ = std::make_unique<V4L2BufferCache>(*buffers);\n> >   \tmemoryType_ = V4L2_MEMORY_MMAP;\n> >   \n> >   \treturn ret;\n> > @@ -1599,7 +1598,7 @@ int V4L2VideoDevice::importBuffers(unsigned int count)\n> >   \tif (ret)\n> >   \t\treturn ret;\n> >   \n> > -\tcache_ = new V4L2BufferCache(count);\n> > +\tcache_ = std::make_unique<V4L2BufferCache>(count);\n> >   \n> >   \tLOG(V4L2, Debug) << \"Prepared to import \" << count << \" buffers\";\n> >   \n> > @@ -1621,8 +1620,7 @@ int V4L2VideoDevice::releaseBuffers()\n> >   \n> >   \tLOG(V4L2, Debug) << \"Releasing buffers\";\n> >   \n> > -\tdelete cache_;\n> > -\tcache_ = nullptr;\n> > +\tcache_.reset();\n> >   \n> >   \treturn requestBuffers(0, memoryType_);\n> >   }\n> > @@ -2197,14 +2195,12 @@ V4L2PixelFormat V4L2VideoDevice::toV4L2PixelFormat(const PixelFormat &pixelForma\n> >   V4L2M2MDevice::V4L2M2MDevice(const std::string &deviceNode)\n> >   \t: deviceNode_(deviceNode)\n> >   {\n> > -\toutput_ = new V4L2VideoDevice(deviceNode);\n> > -\tcapture_ = new V4L2VideoDevice(deviceNode);\n> > +\toutput_ = std::make_unique<V4L2VideoDevice>(deviceNode);\n> > +\tcapture_ = std::make_unique<V4L2VideoDevice>(deviceNode);\n> >   }\n> >   \n> >   V4L2M2MDevice::~V4L2M2MDevice()\n> >   {\n> > -\tdelete capture_;\n> > -\tdelete output_;\n> >   }\n> >   \n> >   /**\n> > diff --git a/src/v4l2/v4l2_camera.cpp b/src/v4l2/v4l2_camera.cpp\n> > index 94d138cd5710..412ab4ea678e 100644\n> > --- a/src/v4l2/v4l2_camera.cpp\n> > +++ b/src/v4l2/v4l2_camera.cpp\n> > @@ -20,7 +20,7 @@ LOG_DECLARE_CATEGORY(V4L2Compat)\n> >   \n> >   V4L2Camera::V4L2Camera(std::shared_ptr<Camera> camera)\n> >   \t: camera_(camera), controls_(controls::controls), isRunning_(false),\n> > -\t  bufferAllocator_(nullptr), efd_(-1), bufferAvailableCount_(0)\n> > +\t  efd_(-1), bufferAvailableCount_(0)\n> >   {\n> >   \tcamera_->requestCompleted.connect(this, &V4L2Camera::requestComplete);\n> >   }\n> > @@ -43,7 +43,7 @@ int V4L2Camera::open(StreamConfiguration *streamConfig)\n> >   \t\treturn -EINVAL;\n> >   \t}\n> >   \n> > -\tbufferAllocator_ = new FrameBufferAllocator(camera_);\n> > +\tbufferAllocator_ = std::make_unique<FrameBufferAllocator>(camera_);\n> >   \n> >   \t*streamConfig = config_->at(0);\n> >   \treturn 0;\n> > @@ -53,8 +53,7 @@ void V4L2Camera::close()\n> >   {\n> >   \trequestPool_.clear();\n> >   \n> > -\tdelete bufferAllocator_;\n> > -\tbufferAllocator_ = nullptr;\n> > +\tbufferAllocator_.reset();\n> >   \n> >   \tcamera_->release();\n> >   }\n> > diff --git a/src/v4l2/v4l2_camera.h b/src/v4l2/v4l2_camera.h\n> > index 9bd161b909de..3d09ae7d6057 100644\n> > --- a/src/v4l2/v4l2_camera.h\n> > +++ b/src/v4l2/v4l2_camera.h\n> > @@ -80,7 +80,7 @@ private:\n> >   \tbool isRunning_;\n> >   \n> >   \tlibcamera::Mutex bufferLock_;\n> > -\tlibcamera::FrameBufferAllocator *bufferAllocator_;\n> > +\tstd::unique_ptr<libcamera::FrameBufferAllocator> bufferAllocator_;\n> >   \n> >   \tstd::vector<std::unique_ptr<libcamera::Request>> requestPool_;\n> >   \n> > diff --git a/src/v4l2/v4l2_compat_manager.cpp b/src/v4l2/v4l2_compat_manager.cpp\n> > index f53fb300dde8..a92f2e2944fc 100644\n> > --- a/src/v4l2/v4l2_compat_manager.cpp\n> > +++ b/src/v4l2/v4l2_compat_manager.cpp\n> > @@ -54,25 +54,21 @@ V4L2CompatManager::~V4L2CompatManager()\n> >   {\n> >   \tfiles_.clear();\n> >   \tmmaps_.clear();\n> > +\tproxies_.clear();\n> >   \n> > -\tif (cm_) {\n> > -\t\tproxies_.clear();\n> > +\tif (cm_)\n> >   \t\tcm_->stop();\n> > -\t\tdelete cm_;\n> > -\t\tcm_ = nullptr;\n> > -\t}\n> >   }\n> >   \n> >   int V4L2CompatManager::start()\n> >   {\n> > -\tcm_ = new CameraManager();\n> > +\tcm_ = std::make_unique<CameraManager>();\n> >   \n> >   \tint ret = cm_->start();\n> >   \tif (ret) {\n> >   \t\tLOG(V4L2Compat, Error) << \"Failed to start camera manager: \"\n> >   \t\t\t\t       << strerror(-ret);\n> > -\t\tdelete cm_;\n> > -\t\tcm_ = nullptr;\n> > +\t\tcm_.reset();\n> >   \t\treturn ret;\n> >   \t}\n> >   \n> > @@ -83,10 +79,8 @@ int V4L2CompatManager::start()\n> >   \t * created here to wrap a camera device.\n> >   \t */\n> >   \tauto cameras = cm_->cameras();\n> > -\tfor (auto [index, camera] : utils::enumerate(cameras)) {\n> > -\t\tV4L2CameraProxy *proxy = new V4L2CameraProxy(index, camera);\n> > -\t\tproxies_.emplace_back(proxy);\n> > -\t}\n> > +\tfor (auto [index, camera] : utils::enumerate(cameras))\n> > +\t\tproxies_.emplace_back(std::make_unique<V4L2CameraProxy>(index, camera));\n> >   \n> >   \treturn 0;\n> >   }\n> > diff --git a/src/v4l2/v4l2_compat_manager.h b/src/v4l2/v4l2_compat_manager.h\n> > index f7c6f1228282..13673d604a63 100644\n> > --- a/src/v4l2/v4l2_compat_manager.h\n> > +++ b/src/v4l2/v4l2_compat_manager.h\n> > @@ -61,7 +61,7 @@ private:\n> >   \n> >   \tFileOperations fops_;\n> >   \n> > -\tlibcamera::CameraManager *cm_;\n> > +\tstd::unique_ptr<libcamera::CameraManager> cm_;\n> >   \n> >   \tstd::vector<std::unique_ptr<V4L2CameraProxy>> proxies_;\n> >   \tstd::map<int, std::shared_ptr<V4L2CameraFile>> files_;","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 36AD5BE173\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 23 Apr 2026 19:16:18 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 5F2AA62F57;\n\tThu, 23 Apr 2026 21:16:17 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id AF8A562010\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 23 Apr 2026 21:16:15 +0200 (CEST)","from killaraus.ideasonboard.com\n\t(2001-14ba-703d-e500--2a1.rev.dnainternet.fi\n\t[IPv6:2001:14ba:703d:e500::2a1])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 28B81802;\n\tThu, 23 Apr 2026 21:14:36 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"mx1HzSbg\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1776971676;\n\tbh=wr9jQXHD7m/ZtzlJ1vvpE7dy46WapHKWwCOdaDkw8Ho=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=mx1HzSbg5Byo8Z8e2NuWQiZAC7W+QjL8r6ZkP0+0FYSarOCgLmI3Dk4GxaCl9cXCO\n\tSaIcH0lm77kg+dy3RN41941wCAv2njCLcX128nez7GAIrMO3CSTtPMht61Ao7hhBlS\n\tUBMzBE05GNy7hoCLVdbfHGz9Cql9evqURo9yLMho=","Date":"Thu, 23 Apr 2026 22:16:14 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH v2 03/42] libcamera: Replace plain pointers with\n\tstd::unique<>","Message-ID":"<20260423191614.GB3086691@killaraus.ideasonboard.com>","References":"<20260407153427.1825999-1-laurent.pinchart@ideasonboard.com>\n\t<20260407153427.1825999-4-laurent.pinchart@ideasonboard.com>\n\t<b80b4ca1-6b05-4716-acba-3a2cf35c0eb5@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<b80b4ca1-6b05-4716-acba-3a2cf35c0eb5@ideasonboard.com>","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>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]