Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
thread_safe_fftw.h
1// SPDX-FileCopyrightText: © 2025 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#pragma once
5
6#include <memory>
7
8#include "utils/types.h"
9
10#ifdef __linux__
11# define ENABLE_THREAD_SAFE_FFTW 1
12#else
13# define ENABLE_THREAD_SAFE_FFTW 0
14#endif
15
16#if ENABLE_THREAD_SAFE_FFTW
17# include <dlfcn.h>
18#endif
19
20class ThreadSafeFFTW
21{
22public:
23 ThreadSafeFFTW ()
24 {
25#if ENABLE_THREAD_SAFE_FFTW
26 load_and_make_thread_safe (
27 "libfftw3_threads.so.3", "fftw_make_planner_thread_safe");
28 load_and_make_thread_safe (
29 "libfftw3f_threads.so.3", "fftwf_make_planner_thread_safe");
30 load_and_make_thread_safe (
31 "libfftw3l_threads.so.3", "fftwl_make_planner_thread_safe");
32 load_and_make_thread_safe (
33 "libfftw3q_threads.so.3", "fftwq_make_planner_thread_safe");
34#endif
35 }
36
37 Z_DISABLE_COPY_MOVE (ThreadSafeFFTW)
38
39private:
40#if ENABLE_THREAD_SAFE_FFTW
41 struct LibHandleDeleter
42 {
43 void operator() (void * handle) const noexcept
44 {
45 if (handle)
46 dlclose (handle);
47 }
48 };
49
50 using LibHandle = std::unique_ptr<void, LibHandleDeleter>;
51
52 void load_and_make_thread_safe (const char * libname, const char * funcname)
53 {
54 LibHandle lib (dlopen (libname, RTLD_LAZY));
55 if (!lib)
56 return;
57
58 using ThreadSafeFunc = void (*) ();
59 if (
60 auto func = reinterpret_cast<ThreadSafeFunc> (dlsym (lib.get (), funcname)))
61 {
62 func ();
63 }
64
65 // Keep the library loaded
66 lib.release (); // Leak intentionally - we need these to stay loaded
67 }
68#endif
69};