From 4384f577807f9275d3b2e6544bfc0f3fbd840d35 Mon Sep 17 00:00:00 2001 From: Gigon Bae Date: Fri, 27 Oct 2023 01:45:47 -0700 Subject: [PATCH] Fix memory corruption issue in ThreadBatchDataLoader - Return a shared pointer of CuImageIterator, taking ownership of CuImageIterator instance, instead of returning a copy of CuImageIterator - Do not create new instance for CuImageIterator when __iter__ is called. Instead, return self. - Wait until all threads are finished in ThreadBatchDataLoader destructor Signed-off-by: Gigon Bae --- cpp/src/loader/thread_batch_data_loader.cpp | 5 ++++- python/pybind11/cucim_py.cpp | 10 +++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/cpp/src/loader/thread_batch_data_loader.cpp b/cpp/src/loader/thread_batch_data_loader.cpp index 89de8e677..0b3ba3af4 100644 --- a/cpp/src/loader/thread_batch_data_loader.cpp +++ b/cpp/src/loader/thread_batch_data_loader.cpp @@ -1,6 +1,6 @@ /* * Apache License, Version 2.0 - * Copyright 2021 NVIDIA Corporation + * Copyright 2021-2023 NVIDIA Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -86,6 +86,9 @@ ThreadBatchDataLoader::ThreadBatchDataLoader(LoadFunc load_func, ThreadBatchDataLoader::~ThreadBatchDataLoader() { + // Wait until all tasks are done. + while (wait_batch() > 0); + cucim::io::DeviceType device_type = out_device_.type(); for (auto& raster_ptr : raster_data_) { diff --git a/python/pybind11/cucim_py.cpp b/python/pybind11/cucim_py.cpp index a79ae103f..bb8c37af8 100644 --- a/python/pybind11/cucim_py.cpp +++ b/python/pybind11/cucim_py.cpp @@ -200,7 +200,7 @@ PYBIND11_MODULE(_cucim, m) }, py::call_guard()); - py::class_>(m, "CuImageIterator") // + py::class_, std::shared_ptr>>(m, "CuImageIterator") // .def(py::init, bool>(), doc::CuImageIterator::doc_CuImageIterator, py::arg("cuimg"), // py::arg("ending") = false, py::call_guard()) @@ -212,8 +212,8 @@ PYBIND11_MODULE(_cucim, m) py::call_guard()) .def( "__iter__", // - [](CuImageIterator& it) { // - return CuImageIterator(it); // + [](CuImageIterator* it) { // + return it; // }, // py::call_guard()) .def("__next__", &py_cuimage_iterator_next, py::call_guard()) @@ -517,11 +517,11 @@ py::object py_read_region(const CuImage& cuimg, auto loader = region_ptr->loader(); if (batch_size > 1 || (loader && loader->size() > 1)) { - auto iter_ptr = region_ptr->begin(); + auto iter_ptr = std::make_shared>(region_ptr->shared_from_this()); py::gil_scoped_acquire scope_guard; - py::object iter = py::cast(iter_ptr); + py::object iter = py::cast(iter_ptr, py::return_value_policy::take_ownership); return iter; }