| 51 | } |
| 52 | |
| 53 | void wf::plugin_manager_t::destroy_plugin(wf::loaded_plugin_t& p) |
| 54 | { |
| 55 | LOGD("Unloading plugin ", p.so_path); |
| 56 | p.instance->fini(); |
| 57 | p.instance.reset(); |
| 58 | |
| 59 | /* dlopen()/dlclose() do reference counting, so we should close the plugin |
| 60 | * as many times as we opened it. |
| 61 | * |
| 62 | * We also need to close the handle after deallocating the plugin, otherwise |
| 63 | * we unload its destructor before calling it. |
| 64 | * |
| 65 | * Note however, that dlclose() is merely a "statement of intent" as per |
| 66 | * POSIX[1]: |
| 67 | * - On glibc[2], this decreases the reference count and potentially unloads |
| 68 | * the binary. |
| 69 | * - On musl-libc[3] this is a noop. |
| 70 | * |
| 71 | * [1]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/dlclose.html |
| 72 | * [2]: https://man7.org/linux/man-pages/man3/dlclose.3.html |
| 73 | * [3]: |
| 74 | * https://wiki.musl-libc.org/functional-differences-from-glibc.html#Unloading-libraries |
| 75 | * */ |
| 76 | if (p.so_handle && enable_so_unloading) |
| 77 | { |
| 78 | dlclose(p.so_handle); |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | static bool check_plugin_api_version(const std::string& path, bool can_unload_so) |
| 83 | { |