Я работаю над плагином (GNU C ++ 7.5.0 / C ++ 14 / Ubuntu 18 / amd64), который загружается через динамическое связывание c во время выполнения. Когда вызывается Test-> run (),
using namespace std;
class Test {
thread t;
void _run() {
this_thread::sleep_for(10ms);
}
void run() {
t = thread(&Test::_run, this);
t.join();
}
}
файл общего объекта (.so) перестает выгружаться из основной программы.
Этого не происходит при вызове метода-члена другого класса или функции stati c.
В чем проблема, и есть ли какие-либо исправления, кроме вопросов реструктуризации?
Хост плагина, о котором идет речь, - Reaper (https://www.reaper.fm/ ), поэтому я не могу точно сказать, что происходит на стороне dlclose / host, но я знаю, что класс Test не деконструируется. Но это всегда так, даже когда выгрузка работает.
Обновление
Заменил this_thread :: sleep_for на
this_thread::__sleep_for
, и это как-то работает. Вот включаемый файл <thread>
:
void
__sleep_for(chrono::seconds, chrono::nanoseconds);
/// sleep_for
template<typename _Rep, typename _Period>
inline void
sleep_for(const chrono::duration<_Rep, _Period>& __rtime)
{
if (__rtime <= __rtime.zero())
return;
auto __s = chrono::duration_cast<chrono::seconds>(__rtime);
auto __ns = chrono::duration_cast<chrono::nanoseconds>(__rtime - __s);
#ifdef _GLIBCXX_USE_NANOSLEEP
__gthread_time_t __ts =
{
static_cast<std::time_t>(__s.count()),
static_cast<long>(__ns.count())
};
while (::nanosleep(&__ts, &__ts) == -1 && errno == EINTR)
{ }
#else
__sleep_for(__s, __ns);
#endif
}
Каким-то образом этот шаблонный код создает STB_GNU_UNIQUE, который кажется (см. dlclose () не работает с заводской функцией и сложными состояниями c в функции? ). Опция --no-gnu-unique linker больше не поддерживается.