-
Notifications
You must be signed in to change notification settings - Fork 118
Description
Golang has issues with unloading of libraries ( golang/go#11100 ). This results in app crashes, ungraceful shutdowns and applications hanging during shutdown when go created libraries are dlclose d. As suggested here, the solution is to not unload the library during dlclose, but to keep it open. This is done using RTLD_NODELETE on unix and GET_MODULE_HANDLE_EX_FLAG_PIN for windows.
Due to the semantic differences in the way these flags are to be used, and libloading not providing functions to directly access the os-specific handle, the current solution to do this is something like this
// By default, go builds the libraries with '-Wl -z nodelete' which does not
// unload the go runtime. This isn't respected on mac ( https://github.com/golang/go/issues/11100#issuecomment-932638093 )
// so we need to explicitly load the library with RTLD_NODELETE( which prevents unloading )
#[cfg(unix)]
let library: libloading::Library = unsafe {
const RTLD_NODELETE: i32 = 0x80;
libloading::os::unix::Library::open(
Some(filename.as_ref()),
libloading::os::unix::RTLD_LAZY | libloading::os::unix::RTLD_LOCAL | RTLD_NODELETE,
)
.map(Into::into)
.map_err(libloading_error_to_adbc_error)?
};
// on windows, we emulate the same behaviour by using the GET_MODULE_HANDLE_EX_FLAG_PIN. The `.pin()`
// function implements this.
#[cfg(windows)]
let library: libloading::Library = unsafe {
let library: libloading::os::windows::Library =
libloading::os::windows::Library::new(filename.as_ref())
.map_err(libloading_error_to_adbc_error)?;
library.pin().map_err(libloading_error_to_adbc_error)?;
library.into()
};
PR for reference: apache/arrow-adbc#3844
We were hoping to get these changes merged here to help others who may also face the same issue. If the approach looks good, I'll be happy to do the changes and submit a PR. If you have other ideas on how to implement this, let's discuss those as well.