Skip to content

feature request: add method to dlclose without unloading the library #193

@Pranav2612000

Description

@Pranav2612000

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions