binaryninja/
background_task.rs1use binaryninjacore_sys::*;
18use std::fmt::Debug;
19
20use std::result;
21
22use crate::rc::*;
23use crate::string::*;
24
25pub type Result<R> = result::Result<R, ()>;
26
27pub struct OwnedBackgroundTaskGuard {
29 pub(crate) task: Ref<BackgroundTask>,
30}
31
32impl OwnedBackgroundTaskGuard {
33 pub fn cancel(&self) {
34 self.task.cancel();
35 }
36
37 pub fn is_cancelled(&self) -> bool {
38 self.task.is_cancelled()
39 }
40
41 pub fn set_progress_text(&self, text: &str) {
42 self.task.set_progress_text(text);
43 }
44}
45
46impl Drop for OwnedBackgroundTaskGuard {
47 fn drop(&mut self) {
48 self.task.finish();
49 }
50}
51
52#[derive(PartialEq, Eq, Hash)]
62pub struct BackgroundTask {
63 pub(crate) handle: *mut BNBackgroundTask,
64}
65
66impl BackgroundTask {
67 pub(crate) unsafe fn from_raw(handle: *mut BNBackgroundTask) -> Self {
68 debug_assert!(!handle.is_null());
69
70 Self { handle }
71 }
72
73 pub fn new(initial_text: &str, can_cancel: bool) -> Ref<Self> {
74 let text = initial_text.to_cstr();
75 let handle = unsafe { BNBeginBackgroundTask(text.as_ptr(), can_cancel) };
76 assert!(!handle.is_null());
78 unsafe { Ref::new(Self { handle }) }
79 }
80
81 pub fn enter(&self) -> OwnedBackgroundTaskGuard {
85 OwnedBackgroundTaskGuard {
86 task: self.to_owned(),
87 }
88 }
89
90 pub fn can_cancel(&self) -> bool {
91 unsafe { BNCanCancelBackgroundTask(self.handle) }
92 }
93
94 pub fn is_cancelled(&self) -> bool {
95 unsafe { BNIsBackgroundTaskCancelled(self.handle) }
96 }
97
98 pub fn cancel(&self) {
99 unsafe { BNCancelBackgroundTask(self.handle) }
100 }
101
102 pub fn is_finished(&self) -> bool {
103 unsafe { BNIsBackgroundTaskFinished(self.handle) }
104 }
105
106 pub fn finish(&self) {
107 unsafe { BNFinishBackgroundTask(self.handle) }
108 }
109
110 pub fn progress_text(&self) -> String {
111 unsafe { BnString::into_string(BNGetBackgroundTaskProgressText(self.handle)) }
112 }
113
114 pub fn set_progress_text(&self, text: &str) {
115 let progress_text = text.to_cstr();
116 unsafe { BNSetBackgroundTaskProgressText(self.handle, progress_text.as_ptr()) }
117 }
118
119 pub fn running_tasks() -> Array<BackgroundTask> {
120 unsafe {
121 let mut count = 0;
122 let handles = BNGetRunningBackgroundTasks(&mut count);
123 Array::new(handles, count, ())
124 }
125 }
126}
127
128impl Debug for BackgroundTask {
129 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
130 f.debug_struct("BackgroundTask")
131 .field("progress_text", &self.progress_text())
132 .field("can_cancel", &self.can_cancel())
133 .field("is_cancelled", &self.is_cancelled())
134 .field("is_finished", &self.is_finished())
135 .finish()
136 }
137}
138
139unsafe impl RefCountable for BackgroundTask {
140 unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
141 Ref::new(Self {
142 handle: BNNewBackgroundTaskReference(handle.handle),
143 })
144 }
145
146 unsafe fn dec_ref(handle: &Self) {
147 BNFreeBackgroundTask(handle.handle);
148 }
149}
150
151impl CoreArrayProvider for BackgroundTask {
152 type Raw = *mut BNBackgroundTask;
153 type Context = ();
154 type Wrapped<'a> = Guard<'a, BackgroundTask>;
155}
156
157unsafe impl CoreArrayProviderInner for BackgroundTask {
158 unsafe fn free(raw: *mut *mut BNBackgroundTask, count: usize, _context: &()) {
159 BNFreeBackgroundTaskList(raw, count);
160 }
161 unsafe fn wrap_raw<'a>(raw: &'a *mut BNBackgroundTask, context: &'a ()) -> Self::Wrapped<'a> {
162 Guard::new(BackgroundTask::from_raw(*raw), context)
163 }
164}
165
166impl ToOwned for BackgroundTask {
167 type Owned = Ref<Self>;
168
169 fn to_owned(&self) -> Self::Owned {
170 unsafe { RefCountable::inc_ref(self) }
171 }
172}
173
174unsafe impl Send for BackgroundTask {}
175unsafe impl Sync for BackgroundTask {}