diff --git a/Point_set_processing_3/include/CGAL/compute_average_spacing.h b/Point_set_processing_3/include/CGAL/compute_average_spacing.h index 647af926dbb..82b2b03272b 100644 --- a/Point_set_processing_3/include/CGAL/compute_average_spacing.h +++ b/Point_set_processing_3/include/CGAL/compute_average_spacing.h @@ -243,19 +243,15 @@ compute_average_spacing( #else if (boost::is_convertible::value) { - // tbb::atomic only has default constructor, initialization done in two steps - tbb::atomic advancement; - advancement = 0; - tbb::atomic interrupted; - interrupted = false; - internal::Point_set_processing_3::Parallel_callback - parallel_callback (callback, interrupted, advancement, kd_tree_points.size()); + parallel_callback (callback, kd_tree_points.size()); std::thread* callback_thread = (callback ? new std::thread (parallel_callback) : NULL); std::vector spacings (kd_tree_points.size (), -1); CGAL::internal::Compute_average_spacings - f (tree, k, kd_tree_points, spacings, advancement, interrupted); + f (tree, k, kd_tree_points, spacings, + parallel_callback.advancement(), + parallel_callback.interrupted()); tbb::parallel_for(tbb::blocked_range(0, kd_tree_points.size ()), f); for (unsigned int i = 0; i < spacings.size (); ++ i) diff --git a/Point_set_processing_3/include/CGAL/internal/Parallel_callback.h b/Point_set_processing_3/include/CGAL/internal/Parallel_callback.h index b6185059b23..282e3e69d57 100644 --- a/Point_set_processing_3/include/CGAL/internal/Parallel_callback.h +++ b/Point_set_processing_3/include/CGAL/internal/Parallel_callback.h @@ -33,36 +33,70 @@ namespace Point_set_processing_3 { class Parallel_callback { - const cpp11::function& callback; - tbb::atomic& advancement; - tbb::atomic& interrupted; - std::size_t size; - + const cpp11::function& m_callback; + tbb::atomic* m_advancement; + tbb::atomic* m_interrupted; + std::size_t m_size; + bool m_creator; + public: Parallel_callback (const cpp11::function& callback, - tbb::atomic& interrupted, - tbb::atomic& advancement, - std::size_t size) - : callback (callback) - , advancement (advancement) - , interrupted (interrupted) - , size (size) - { } + std::size_t size, + std::size_t advancement = 0, + bool interrupted = false) + : m_callback (callback) + , m_advancement (new tbb::atomic()) + , m_interrupted (new tbb::atomic()) + , m_size (size) + , m_creator (true) + { + // tbb::atomic only has default constructor, initialization done in two steps + *m_advancement = advancement; + *m_interrupted = interrupted; + } + + Parallel_callback (const Parallel_callback& other) + : m_callback (other.m_callback) + , m_advancement (other.m_advancement) + , m_interrupted (other.m_interrupted) + , m_size (other.m_size) + , m_creator (false) + { + + } + + Parallel_callback& operator= (const Parallel_callback& other) + { + Parallel_callback out (other); + return out; + } + + ~Parallel_callback () + { + if (m_creator) + { + delete m_advancement; + delete m_interrupted; + } + } + + tbb::atomic& advancement() { return *m_advancement; } + tbb::atomic& interrupted() { return *m_interrupted; } void operator()() { tbb::tick_count::interval_t sleeping_time(0.00001); - while (advancement != size) + while (*m_advancement != m_size) { - if (!callback (advancement / double(size))) + if (!m_callback (*m_advancement / double(m_size))) { - interrupted = true; + *m_interrupted = true; return; } std::this_thread::sleep_for(sleeping_time); } - callback (1.); + m_callback (1.); } };