extism_runtime/
plugin_ref.rs1use crate::*;
2
3pub struct PluginRef<'a> {
5 pub id: PluginIndex,
6 running: bool,
7 pub(crate) epoch_timer_tx: std::sync::mpsc::SyncSender<TimerAction>,
8 plugin: *mut Plugin,
9 _t: std::marker::PhantomData<&'a ()>,
10}
11
12impl<'a> PluginRef<'a> {
13 pub(crate) fn start_call(mut self, is_start: bool) -> Self {
15 trace!("PluginRef::start_call: {}", self.id,);
16
17 let plugin = unsafe { &mut *self.plugin };
18 if is_start {
19 if let Err(e) = plugin.reset_store() {
20 error!("Call to Plugin::reset_store failed: {e:?}");
21 }
22 }
23
24 if plugin.instance.is_none() {
25 trace!("Plugin::instance is none, instantiating");
26 if let Err(e) = plugin.instantiate() {
27 error!("Plugin::instantiate failed: {e:?}");
28 plugin.error(e, ());
29 }
30 }
31
32 self.running = true;
33 self
34 }
35
36 pub fn new(ctx: &'a mut Context, plugin_id: PluginIndex, clear_error: bool) -> Option<Self> {
40 trace!("Loading plugin {plugin_id}");
41
42 let epoch_timer_tx = ctx.epoch_timer_tx.clone();
43
44 let plugin = if let Some(plugin) = ctx.plugin(plugin_id) {
45 plugin
46 } else {
47 error!("Plugin does not exist: {plugin_id}");
48 return ctx.error(format!("Plugin does not exist: {plugin_id}"), None);
49 };
50
51 let plugin = unsafe { &mut *plugin };
52
53 if clear_error {
54 trace!("Clearing context error");
55 ctx.error = None;
56 trace!("Clearing plugin error: {plugin_id}");
57 plugin.clear_error();
58 }
59
60 Some(PluginRef {
61 id: plugin_id,
62 plugin,
63 epoch_timer_tx,
64 _t: std::marker::PhantomData,
65 running: false,
66 })
67 }
68}
69
70impl<'a> AsRef<Plugin> for PluginRef<'a> {
71 fn as_ref(&self) -> &Plugin {
72 unsafe { &*self.plugin }
73 }
74}
75
76impl<'a> AsMut<Plugin> for PluginRef<'a> {
77 fn as_mut(&mut self) -> &mut Plugin {
78 unsafe { &mut *self.plugin }
79 }
80}
81
82impl<'a> Drop for PluginRef<'a> {
83 fn drop(&mut self) {
84 trace!("Dropping PluginRef {}", self.id);
85 if self.running {
86 let plugin = self.as_mut();
87
88 if let Err(e) = plugin.stop_timer() {
90 let id = plugin.timer_id;
91 error!("Failed to stop timeout manager for {id}: {e:?}");
92 }
93 }
94 }
95}