Repository: opencv
Issue: ThreadSanitizer reported data race
Labels: priority: low,category: core

### System Information

OpenCV version: 4.7.0
OS: Ubuntu 16.04/20.04
Compiler: gcc-12


### Detailed description

While running my unit-test with ASAN, it reported data race condition during my image rotation code. Would appreciate some help on workaround. 

Not sure if this is a similar issue to: https://github.com/opencv/opencv/issues/19463

```
==================
WARNING: ThreadSanitizer: data race (pid=27199)
  Read of size 1 at 0x7b2400025138 by main thread:
    #0 cv::ThreadPool::run(cv::Range const&, cv::ParallelLoopBody const&, double) /root/toolchain_build/opencv/modules/core/src/parallel_impl.cpp:593 (libopencv_core.so.407+0x30d78b)
    #1 cv::parallel_for_pthreads(cv::Range const&, cv::ParallelLoopBody const&, double) /root/toolchain_build/opencv/modules/core/src/parallel_impl.cpp:750 (libopencv_core.so.407+0x30e140)
    #2 parallel_for_impl /root/toolchain_build/opencv/modules/core/src/parallel.cpp:609 (libopencv_core.so.407+0x2ebad0)
    #3 cv::parallel_for_(cv::Range const&, cv::ParallelLoopBody const&, double) /root/toolchain_build/opencv/modules/core/src/parallel.cpp:520 (libopencv_core.so.407+0x2ebad0)
    #4 cv::hal::warpAffine(int, unsigned char const*, unsigned long, int, int, unsigned char*, unsigned long, int, int, double const*, int, int, double const*) /root/toolchain_build/opencv/modules/imgproc/src/imgwarp.cpp:2694 (libopencv_imgproc.so.407+0x33ad17)
    #5 cv::warpAffine(cv::_InputArray const&, cv::_OutputArray const&, cv::_InputArray const&, cv::Size_<int>, int, int, cv::Scalar_<double> const&) /root/toolchain_build/opencv/modules/imgproc/src/imgwarp.cpp:2813 (libopencv_imgproc.so.407+0x33b4f8)
    #6 fingerprint::rotate(cv::Mat, double) ../libs/dlp/fp20svc/PhashFingerprintGenerator.hpp:51 (dlp_fp20_gen_test+0x4a6ca9)
    #7 fingerprint::PhashFingerprintGenerator::generateFingerprint(cv::Mat) ../libs/dlp/fp20svc/PhashFingerprintGenerator.hpp:116 (dlp_fp20_gen_test+0x4a768d)
    #8 fingerprint::PhashFingerprintGenerator::generateFingerprint(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ../libs/dlp/fp20svc/PhashFingerprintGenerator.hpp:100 (dlp_fp20_gen_test+0x49e655)
    #9 Fp_Generate_all_Test::TestBody() ../libs/dlp/fp20/test/src/DlpFp20GenentorTest.cpp:82 (dlp_fp20_gen_test+0x49e655)
    #10 void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /root/toolchain_build/gtest/googletest/src/gtest.cc:2599 (dlp_fp20_gen_test+0x51eb28)
    #11 void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /root/toolchain_build/gtest/googletest/src/gtest.cc:2635 (dlp_fp20_gen_test+0x51eb28)
    #12 testing::Test::Run() /root/toolchain_build/gtest/googletest/src/gtest.cc:2674 (dlp_fp20_gen_test+0x5011a8)
    #13 testing::TestInfo::Run() /root/toolchain_build/gtest/googletest/src/gtest.cc:2853 (dlp_fp20_gen_test+0x501774)
    #14 testing::TestSuite::Run() /root/toolchain_build/gtest/googletest/src/gtest.cc:3012 (dlp_fp20_gen_test+0x501e7c)
    #15 testing::internal::UnitTestImpl::RunAllTests() /root/toolchain_build/gtest/googletest/src/gtest.cc:5870 (dlp_fp20_gen_test+0x50ea18)
    #16 bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /root/toolchain_build/gtest/googletest/src/gtest.cc:2599 (dlp_fp20_gen_test+0x50212c)
    #17 bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /root/toolchain_build/gtest/googletest/src/gtest.cc:2635 (dlp_fp20_gen_test+0x50212c)
    #18 testing::UnitTest::Run() /root/toolchain_build/gtest/googletest/src/gtest.cc:5444 (dlp_fp20_gen_test+0x50212c)
    #19 RUN_ALL_TESTS() /root/toolchain_build/gtest/googletest/include/gtest/gtest.h:2293 (dlp_fp20_gen_test+0x486811)
    #20 main /root/toolchain_build/gtest/googletest/src/gtest_main.cc:51 (dlp_fp20_gen_test+0x486811)

  Previous write of size 1 at 0x7b2400025138 by thread T2 (mutexes: write M288647245677613328):
    #0 cv::WorkerThread::thread_body() /root/toolchain_build/opencv/modules/core/src/parallel_impl.cpp:410 (libopencv_core.so.407+0x30acf7)
    #1 cv::WorkerThread::thread_loop_wrapper(void*) /root/toolchain_build/opencv/modules/core/src/parallel_impl.cpp:282 (libopencv_core.so.407+0x30b3c9)

  Location is heap block of size 144 at 0x7b24000250e0 allocated by main thread:
    #0 operator new(unsigned long) ../../../../libsanitizer/tsan/tsan_new_delete.cpp:64 (libtsan.so.2+0x84e5f)
    #1 cv::ThreadPool::reconfigure_(unsigned int) /root/toolchain_build/opencv/modules/core/src/parallel_impl.cpp:537 (libopencv_core.so.407+0x30c4da)
    #2 cv::ThreadPool::run(cv::Range const&, cv::ParallelLoopBody const&, double) /root/toolchain_build/opencv/modules/core/src/parallel_impl.cpp:575 (libopencv_core.so.407+0x30d4d5)
    #3 cv::parallel_for_pthreads(cv::Range const&, cv::ParallelLoopBody const&, double) /root/toolchain_build/opencv/modules/core/src/parallel_impl.cpp:750 (libopencv_core.so.407+0x30e140)
    #4 parallel_for_impl /root/toolchain_build/opencv/modules/core/src/parallel.cpp:609 (libopencv_core.so.407+0x2ebad0)
    #5 cv::parallel_for_(cv::Range const&, cv::ParallelLoopBody const&, double) /root/toolchain_build/opencv/modules/core/src/parallel.cpp:520 (libopencv_core.so.407+0x2ebad0)
    #6 cv::hal::warpAffine(int, unsigned char const*, unsigned long, int, int, unsigned char*, unsigned long, int, int, double const*, int, int, double const*) /root/toolchain_build/opencv/modules/imgproc/src/imgwarp.cpp:2694 (libopencv_imgproc.so.407+0x33ad17)
    #7 cv::warpAffine(cv::_InputArray const&, cv::_OutputArray const&, cv::_InputArray const&, cv::Size_<int>, int, int, cv::Scalar_<double> const&) /root/toolchain_build/opencv/modules/imgproc/src/imgwarp.cpp:2813 (libopencv_imgproc.so.407+0x33b4f8)
    #8 fingerprint::rotate(cv::Mat, double) ../libs/dlp/fp20svc/PhashFingerprintGenerator.hpp:51 (dlp_fp20_gen_test+0x4a6ca9)
    #9 fingerprint::PhashFingerprintGenerator::generateFingerprint(cv::Mat) ../libs/dlp/fp20svc/PhashFingerprintGenerator.hpp:116 (dlp_fp20_gen_test+0x4a768d)
    #10 fingerprint::PhashFingerprintGenerator::generateFingerprint(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ../libs/dlp/fp20svc/PhashFingerprintGenerator.hpp:100 (dlp_fp20_gen_test+0x49e655)
    #11 Fp_Generate_all_Test::TestBody() ../libs/dlp/fp20/test/src/DlpFp20GenentorTest.cpp:82 (dlp_fp20_gen_test+0x49e655)
    #12 void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /root/toolchain_build/gtest/googletest/src/gtest.cc:2599 (dlp_fp20_gen_test+0x51eb28)
    #13 void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /root/toolchain_build/gtest/googletest/src/gtest.cc:2635 (dlp_fp20_gen_test+0x51eb28)
    #14 testing::Test::Run() /root/toolchain_build/gtest/googletest/src/gtest.cc:2674 (dlp_fp20_gen_test+0x5011a8)
    #15 testing::TestInfo::Run() /root/toolchain_build/gtest/googletest/src/gtest.cc:2853 (dlp_fp20_gen_test+0x501774)
    #16 testing::TestSuite::Run() /root/toolchain_build/gtest/googletest/src/gtest.cc:3012 (dlp_fp20_gen_test+0x501e7c)
    #17 testing::internal::UnitTestImpl::RunAllTests() /root/toolchain_build/gtest/googletest/src/gtest.cc:5870 (dlp_fp20_gen_test+0x50ea18)
    #18 bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /root/toolchain_build/gtest/googletest/src/gtest.cc:2599 (dlp_fp20_gen_test+0x50212c)
    #19 bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /root/toolchain_build/gtest/googletest/src/gtest.cc:2635 (dlp_fp20_gen_test+0x50212c)
    #20 testing::UnitTest::Run() /root/toolchain_build/gtest/googletest/src/gtest.cc:5444 (dlp_fp20_gen_test+0x50212c)
    #21 RUN_ALL_TESTS() /root/toolchain_build/gtest/googletest/include/gtest/gtest.h:2293 (dlp_fp20_gen_test+0x486811)
    #22 main /root/toolchain_build/gtest/googletest/src/gtest_main.cc:51 (dlp_fp20_gen_test+0x486811)

  Mutex M288647245677613328 is already destroyed.

  Thread T2 (tid=27205, running) created by main thread at:
    #0 pthread_create ../../../../libsanitizer/tsan/tsan_interceptors_posix.cpp:1001 (libtsan.so.2+0x5c862)
    #1 cv::WorkerThread::WorkerThread(cv::ThreadPool&, unsigned int) /root/toolchain_build/opencv/modules/core/src/parallel_impl.cpp:241 (libopencv_core.so.407+0x30974b)
    #2 cv::ThreadPool::reconfigure_(unsigned int) /root/toolchain_build/opencv/modules/core/src/parallel_impl.cpp:537 (libopencv_core.so.407+0x30c4ef)
    #3 cv::ThreadPool::run(cv::Range const&, cv::ParallelLoopBody const&, double) /root/toolchain_build/opencv/modules/core/src/parallel_impl.cpp:575 (libopencv_core.so.407+0x30d4d5)
    #4 cv::parallel_for_pthreads(cv::Range const&, cv::ParallelLoopBody const&, double) /root/toolchain_build/opencv/modules/core/src/parallel_impl.cpp:750 (libopencv_core.so.407+0x30e140)
    #5 parallel_for_impl /root/toolchain_build/opencv/modules/core/src/parallel.cpp:609 (libopencv_core.so.407+0x2ebad0)
    #6 cv::parallel_for_(cv::Range const&, cv::ParallelLoopBody const&, double) /root/toolchain_build/opencv/modules/core/src/parallel.cpp:520 (libopencv_core.so.407+0x2ebad0)
    #7 cv::hal::warpAffine(int, unsigned char const*, unsigned long, int, int, unsigned char*, unsigned long, int, int, double const*, int, int, double const*) /root/toolchain_build/opencv/modules/imgproc/src/imgwarp.cpp:2694 (libopencv_imgproc.so.407+0x33ad17)
    #8 cv::warpAffine(cv::_InputArray const&, cv::_OutputArray const&, cv::_InputArray const&, cv::Size_<int>, int, int, cv::Scalar_<double> const&) /root/toolchain_build/opencv/modules/imgproc/src/imgwarp.cpp:2813 (libopencv_imgproc.so.407+0x33b4f8)
    #9 fingerprint::rotate(cv::Mat, double) ../libs/dlp/fp20svc/PhashFingerprintGenerator.hpp:51 (dlp_fp20_gen_test+0x4a6ca9)
    #10 fingerprint::PhashFingerprintGenerator::generateFingerprint(cv::Mat) ../libs/dlp/fp20svc/PhashFingerprintGenerator.hpp:116 (dlp_fp20_gen_test+0x4a768d)
    #11 fingerprint::PhashFingerprintGenerator::generateFingerprint(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ../libs/dlp/fp20svc/PhashFingerprintGenerator.hpp:100 (dlp_fp20_gen_test+0x49e655)
    #12 Fp_Generate_all_Test::TestBody() ../libs/dlp/fp20/test/src/DlpFp20GenentorTest.cpp:82 (dlp_fp20_gen_test+0x49e655)
    #13 void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /root/toolchain_build/gtest/googletest/src/gtest.cc:2599 (dlp_fp20_gen_test+0x51eb28)
    #14 void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /root/toolchain_build/gtest/googletest/src/gtest.cc:2635 (dlp_fp20_gen_test+0x51eb28)
    #15 testing::Test::Run() /root/toolchain_build/gtest/googletest/src/gtest.cc:2674 (dlp_fp20_gen_test+0x5011a8)
    #16 testing::TestInfo::Run() /root/toolchain_build/gtest/googletest/src/gtest.cc:2853 (dlp_fp20_gen_test+0x501774)
    #17 testing::TestSuite::Run() /root/toolchain_build/gtest/googletest/src/gtest.cc:3012 (dlp_fp20_gen_test+0x501e7c)
    #18 testing::internal::UnitTestImpl::RunAllTests() /root/toolchain_build/gtest/googletest/src/gtest.cc:5870 (dlp_fp20_gen_test+0x50ea18)
    #19 bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /root/toolchain_build/gtest/googletest/src/gtest.cc:2599 (dlp_fp20_gen_test+0x50212c)
    #20 bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /root/toolchain_build/gtest/googletest/src/gtest.cc:2635 (dlp_fp20_gen_test+0x50212c)
    #21 testing::UnitTest::Run() /root/toolchain_build/gtest/googletest/src/gtest.cc:5444 (dlp_fp20_gen_test+0x50212c)
    #22 RUN_ALL_TESTS() /root/toolchain_build/gtest/googletest/include/gtest/gtest.h:2293 (dlp_fp20_gen_test+0x486811)
    #23 main /root/toolchain_build/gtest/googletest/src/gtest_main.cc:51 (dlp_fp20_gen_test+0x486811)

SUMMARY: ThreadSanitizer: data race /root/toolchain_build/opencv/modules/core/src/parallel_impl.cpp:593 in cv::ThreadPool::run(cv::Range const&, cv::ParallelLoopBody const&, double)
==================
```

### Steps to reproduce

Sample code of rotation, Just run it with gTest.

    cv::Ptr<PHash> m_pHashHandle = PHash::create();
    ...
    inline cv::Mat
    rotate(cv::Mat src, double angle)
    {
        cv::Mat dst;
        cv::Point2f pt(src.cols / 2., src.rows / 2.);
        cv::Mat r = cv::getRotationMatrix2D(pt, angle, 1.0);
        cv::warpAffine(src, dst, r, cv::Size(src.cols, src.rows));
        return dst;
    }

    std::vector<uint64_t> generateFingerprint(const cv::Mat &img)
    {
        cv::Mat pHash;
        m_pHashHandle->compute(img, pHash);
        auto hash = convertPhashToNumber(pHash);

        cv::Mat img90 = rotate(img, 90.0);
        cv::Mat pHash90;
        m_pHashHandle->compute(img90, pHash90);
        auto hash90 = convertPhashToNumber(pHash90);

        cv::Mat img180 = rotate(img, 180.0);
        cv::Mat pHash180;
        m_pHashHandle->compute(img180, pHash180);
        auto hash180 = convertPhashToNumber(pHash180);

        cv::Mat img270 = rotate(img, 270.0);
        cv::Mat pHash270;
        m_pHashHandle->compute(img270, pHash270);
        auto hash270 = convertPhashToNumber(pHash270);

        return {hash, hash90, hash180, hash270};
    }


### Issue submission checklist

- [X] I report the issue, it's not a question
- [X] I checked the problem with documentation, FAQ, open issues, forum.opencv.org, Stack Overflow, etc and have not found any solution
- [X] I updated to the latest OpenCV version and the issue is still there
- [X] There is reproducer code and related data files (videos, images, onnx, etc)