Skip to content

Commit

Permalink
Fix shutdown from non-main thread.
Browse files Browse the repository at this point in the history
  • Loading branch information
dvicini committed Sep 12, 2024
1 parent b70dd3b commit 40f3119
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 13 deletions.
3 changes: 3 additions & 0 deletions include/mitsuba/core/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ class MI_EXPORT_LIB Thread : public Object {
/// Return the current thread
static Thread *thread();

/// Return whether the current thread data structure has been initialized.
static bool has_initialized_thread();

/// Sleep for a certain amount of time (in milliseconds)
static void sleep(uint32_t ms);

Expand Down
5 changes: 2 additions & 3 deletions src/core/logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,8 @@ void Logger::static_initialization() {
#endif
}

void Logger::static_shutdown() {
Thread::thread()->set_logger(nullptr);
}
// Removal of logger from main thread is handled in thread.cpp.
void Logger::static_shutdown() { }

size_t Logger::appender_count() const {
return d->appenders.size();
Expand Down
9 changes: 7 additions & 2 deletions src/core/thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,10 @@ Thread* Thread::thread() {
return self_val;
}

bool Thread::has_initialized_thread() {
return self != nullptr;
}

bool Thread::is_running() const {
return d->running;
}
Expand Down Expand Up @@ -558,8 +562,9 @@ void Thread::static_shutdown() {
}
thread_registry.clear();
}

thread()->d->running = false;
main_thread->d->logger = nullptr;
main_thread->d->fresolver = nullptr;
main_thread->d->running = false;
self = nullptr;
main_thread = nullptr;
#if defined(__linux__) || defined(__APPLE__)
Expand Down
15 changes: 7 additions & 8 deletions src/python/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,12 @@ NB_MODULE(mitsuba_ext, m) {
Class::static_remove_functors();
StructConverter::static_shutdown();

/* When the main thread's lifetime was shared with Python, it would be
* detected as a nanbonid leak as the last reference is held by C++.
* Calling `Thread::static_shutdown()` deletes this last reference,
* however the main thread is still needed to clean up other parts of
* the system. The solution is therefore to temporarily clean it up
* and then re-build it such that Python can no longer track it. */
if(Thread::thread()->self_py()) {
/* Potentially re-initialize the threading system:
* 1) Deleting and re-initializing threading prevents a Nanobind leak
* if the lifetime of the main thread was shared with Python.
* 2) Additionally, this can ensure correct shutdown if the shutdown
* happens on another thread than the initialization. */
if (!Thread::has_initialized_thread() || Thread::thread()->self_py()) {
Thread::static_shutdown();
Thread::static_initialization();
}
Expand All @@ -202,7 +201,7 @@ NB_MODULE(mitsuba_ext, m) {
}
}));

/* Callback function cleanup static data strucutres, this should be called
/* Callback function cleanup static data structures, this should be called
* when the module is being deallocated */
nanobind_module_def_mitsuba_ext.m_free = [](void *) {
Profiler::static_shutdown();
Expand Down

0 comments on commit 40f3119

Please sign in to comment.