I'm working on a plugin (GNU C++ 7.5.0/C++14/Ubuntu 18/amd64) that is being loaded through dynamic linking at runtime. When Test->run() gets called,
using namespace std;
class Test {
thread t;
void _run() {
this_thread::sleep_for(10ms);
}
void run() {
t = thread(&Test::_run, this);
t.join();
}
}
the shared object file (.so) stops getting unloaded from the main program.
This does not happen when calling a member method of a different class or a static function.
What's the issue and is there any fix besides restructuring things?
The plugin host in question is Reaper (https://www.reaper.fm/), so I can't really say what's going on on the dlclose/host side, but I know that the Test class does not get deconstructed. But that's always the case, even when the unloading works.
Update
Replaced this_thread::sleep_for with
this_thread::__sleep_for
and that somehow works. Here is the <thread>
include file:
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
}
Somehow, that template code is producing an STB_GNU_UNIQUE it seems (see dlclose() doesn't work with factory function & complex static in function?). The --no-gnu-unique linker option seems not supported any more.