Search code examples
c++cgal

Problem with multi-threaded construction of Nef Polyhedrons from a same Polyhedron


I have a multi-thread program in which a set of 3D Nef Polyhedrons might be constructed from a same polyhedron, the simplified code can be demonstrated as:

#include <iostream>
#include <vector>
#include <fstream>
#include <future>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Nef_polyhedron_3.h>
#include <CGAL/boost/graph/convert_nef_polyhedron_to_polygon_mesh.h>
#include <CGAL/Polygon_mesh_processing/measure.h>
#include <CGAL/Polygon_mesh_processing/triangulate_faces.h>

typedef CGAL::Exact_predicates_exact_constructions_kernel Exact_kernel;
typedef CGAL::Polyhedron_3<Exact_kernel> Polyhedron;
typedef CGAL::Nef_polyhedron_3<Exact_kernel> Nef_polyhedron;

int main()
{
    std::ifstream ifs("mesh_a.off");
    Polyhedron poly;
    CGAL::read_off(ifs, poly);
    CGAL::Polygon_mesh_processing::triangulate_faces(poly);

    std::vector<std::future<void>> futureVec;
    for (int i = 0; i < 10; i++) {
        auto fun = [&poly]() {
            Nef_polyhedron N1(poly);
            std::cout << "test" << std::endl;
        };
        futureVec.push_back(std::async(std::launch::async, fun));
    }
    for (size_t i = 0; i < futureVec.size(); i++)
        futureVec[i].get();

    return 0;
}

The content of mesh_a.off file is:

OFF
16 6 0
0.63 0 0
1.26 0 0
0.965876 0.294124 0
0.909198 0.245717 0
0.845645 0.206772 0
0.776783 0.178248 0
0.704306 0.160848 0
0.63 0.155 0
0.63 0 0.5
1.26 0 0.5
0.965876 0.294124 0.5
0.909198 0.245717 0.5
0.845645 0.206772 0.5
0.776783 0.178248 0.5
0.704306 0.160848 0.5
0.63 0.155 0.5
8  7 6 5 4 3 2 1 0
8  8 9 10 11 12 13 14 15
4  0 1 9 8
4  1 2 10 9
12  2 3 4 5 6 7 15 14 13 12 11 10
4  7 0 8 15

If the code above works normally, the word "test" should be printed 10 times. However, the number of print times differs at each execution and at most time it doesn't print anything. It seems something wrong with construction of Nef Polyhedron causing an unexpected thread quit, although no exception throw. The print behavior performs normally if I move the line of print code to the upper line of Nef Polyhedron construction.

I run the program on Windows and the IDE is Visual Studio 2019.

So what's wrong with this code? How can I construct Nef polyhedrons from a same polyhedron using multi-thread?


Solution

  • On linux, your program aborts with

    free(): corrupted unsorted chunks

    CGAL::Exact_predicates_exact_constructions_kernel is not thread-safe currently, reading the same number in 2 threads can lead to corruption. There is a PR to make it thread-safe: https://github.com/CGAL/cgal/pull/5402 but it hasn't been merged yet.

    Without this branch, one workaround could be to use Simple_cartesian<mpq_class> or a similar kernel, but that's going to be slower than doing your construction sequentially with Epeck.