unfortunately, this whole project was doomed from the start

unloading libraries is unsupported/will lead to serious runtime issues on most if not all platforms
This commit is contained in:
lever1209 2024-08-22 00:03:50 -03:00
commit 75f26afd01
Signed by: lever1209
GPG key ID: AD770D25A908AFF4
3 changed files with 28 additions and 96 deletions

View file

@ -13,7 +13,6 @@ pub type RegisterFn = *mut dyn Plugin;
#[derive(Debug)] #[derive(Debug)]
pub enum PluginResult { pub enum PluginResult {
Ok, Ok,
FunctionNotFound,
Other(String), Other(String),
} }

View file

@ -16,11 +16,11 @@ impl Plugin for ExamplePlugin {
fn register_functions(&self) -> HashMap<String, AsyncFn> { fn register_functions(&self) -> HashMap<String, AsyncFn> {
let mut map = HashMap::new(); let mut map = HashMap::new();
map.insert("example_function".to_string(), example_function as AsyncFn); map.insert("example_function".to_string(), example_function as AsyncFn);
dbg!(map) map
} }
fn unregister_functions(&self) -> Vec<String> { fn unregister_functions(&self) -> Vec<String> {
dbg!(vec!["example_function".to_string()]) vec!["example_function".to_string()]
} }
} }

View file

@ -1,15 +1,13 @@
pub use host_tools::tokio;
use host_tools::tokio::runtime::Handle; use host_tools::tokio::runtime::Handle;
use host_tools::tokio::sync::RwLock; use host_tools::tokio::sync::RwLock;
use host_tools::tracing::{error, info}; use host_tools::tracing::{error, info, warn};
use host_tools::{AsyncFn, PluginResult, RegisterFn}; use host_tools::{AsyncFn, PluginResult, RegisterFn};
use libloading::{Library, Symbol}; use libloading::{Library, Symbol};
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
fn get_name() -> String {
"example_function".to_string()
}
async fn load_plugin( async fn load_plugin(
lib_path: &str, lib_path: &str,
function_map: Arc<RwLock<HashMap<String, AsyncFn>>>, function_map: Arc<RwLock<HashMap<String, AsyncFn>>>,
@ -34,113 +32,48 @@ async fn unload_plugin(
unsafe { lib.get(b"register_plugin") }.map_err(|e| PluginResult::Other(e.to_string()))?; unsafe { lib.get(b"register_plugin") }.map_err(|e| PluginResult::Other(e.to_string()))?;
let plugin_instance = unsafe { Box::from_raw(plugin()) }; let plugin_instance = unsafe { Box::from_raw(plugin()) };
info!("found plugin instance");
let functions = plugin_instance.unregister_functions(); let functions = plugin_instance.unregister_functions();
info!("runregister functions"); let mut map = function_map.write().await;
{ for function in functions {
let mut map = function_map.write().await; map.remove(&function);
for function in functions {
map.remove(&function);
}
} }
drop(lib);
info!("removed functions");
let _ = lib;
info!("unloaded lib");
Ok(()) Ok(())
} }
//#[tokio::main(flavor = "multi_thread", worker_threads = 6)]
//async fn main() -> Result<(), PluginResult> {
// tracing::subscriber::set_global_default(tracing_subscriber::fmt().finish()).unwrap();
// let function_map: Arc<RwLock<HashMap<String, AsyncFn>>> = Arc::new(RwLock::new(HashMap::new()));
// // Load the plugin #[host_tools::tokio::main]
// info!("Loading plugin");
// let plugin_lib = load_plugin("target/release/libtesting.so", Arc::clone(&function_map)).await?;
// info!("Plugin loaded");
// let function_name = get_name();
// let mut handles = Vec::new();
// // Start tasks
// info!("Starting task execution loop");
// for i in 0..3 {
// if let Some(function) = function_map.read().await.get(&function_name).cloned() {
// info!("Starting task for function '{}'", function_name);
// let handle = function(Handle::current().clone());
// handles.push(handle);
// } else {
// info!("Function '{}' not found in map", function_name);
// }
// }
// // Await all tasks
// info!("Awaiting tasks to complete");
// for (i, handle) in handles.into_iter().enumerate() {
// match handle.await.unwrap() {
// PluginResult::Ok => info!("Task {} exited with Ok", i),
// PluginResult::FunctionNotFound => info!("Task {} found FunctionNotFound", i),
// PluginResult::Other(err) => error!("Task {} exited with error: `{}`", i, err),
// }
// }
// // Unload the plugin
// info!("Unloading plugin");
// unload_plugin(plugin_lib, Arc::clone(&function_map)).await?;
// info!("Plugin unloaded successfully");
// // Ensure all tasks are done
// info!("Waiting for all tasks to complete");
// tokio::time::sleep(tokio::time::Duration::from_secs(1)).await; // Add a short sleep to ensure tasks finish
// info!("Exiting main function");
// Ok(())
//}
#[host_tools::tokio::main(
crate = "host_tools::tokio",
flavor = "multi_thread",
worker_threads = 6
)]
async fn main() -> Result<(), PluginResult> { async fn main() -> Result<(), PluginResult> {
host_tools::tracing::subscriber::set_global_default(host_tools::tracing_subscriber::fmt().finish()) host_tools::tracing::subscriber::set_global_default(
.unwrap(); host_tools::tracing_subscriber::fmt().finish(),
)
.unwrap();
let function_map: Arc<RwLock<HashMap<String, AsyncFn>>> = Arc::new(RwLock::new(HashMap::new())); let function_map: Arc<RwLock<HashMap<String, AsyncFn>>> = Arc::new(RwLock::new(HashMap::new()));
let plugin_lib = load_plugin("target/release/libtesting.so", Arc::clone(&function_map)).await?; let function_name = "example_function".to_string();
let function_name = get_name(); let mut tasks = vec![];
//for i in 0..3 { for _ in 0..16 {
// if let Some(function) = function_map.read().await.get(&function_name).cloned() { let plugin_lib =
// match function(Handle::current().clone()).await.unwrap() { load_plugin("target/release/libtesting.so", Arc::clone(&function_map)).await?;
// PluginResult::Ok => info!("Function {i} exited with Ok"),
// PluginResult::FunctionNotFound => todo!(),
// PluginResult::Other(err) => error!("Function exited with error: `{err}`"),
// };
// } else {
// println!("Function '{}' not found", function_name);
// }
//}
for i in 0..3 {
if let Some(function) = function_map.read().await.get(&function_name).cloned() { if let Some(function) = function_map.read().await.get(&function_name).cloned() {
tasks.push(host_tools::tokio::spawn(async move {
let join_handle = function(Handle::current().clone()); let join_handle = function(Handle::current().clone());
match join_handle.await.unwrap() { match join_handle.await.unwrap() {
PluginResult::Ok => info!("Function {i} exited with Ok"), PluginResult::Ok => {}
PluginResult::FunctionNotFound => todo!(),
PluginResult::Other(err) => error!("Function exited with error: `{err}`"), PluginResult::Other(err) => error!("Function exited with error: `{err}`"),
}; };
}));
} else { } else {
println!("Function '{}' not found", function_name); warn!("Function '{}' not found", function_name);
} }
unload_plugin(plugin_lib, Arc::clone(&function_map)).await?;
} }
info!("unloading"); for task in tasks {
unload_plugin(plugin_lib, Arc::clone(&function_map)).await?; info!("awaiting {task:?}");
task.await.unwrap();
}
Ok(()) Ok(())
} }