Skip to content

Commit

Permalink
feat: add deadlock detection at CI
Browse files Browse the repository at this point in the history
add [lockbud](https://github.com/BurtonQin/lockbud.git) for detection
**somes** deadlocks.

Need to remove the macros lock since lockbud would not be able to give
the right location with it.

The following command was used on the source code to reduce manual
modifications.
`
fd "*.rs" src/| xargs -I {} sd 'lock!\(([^\)]*)\)'
'$1.lock().unwrap()'{}
`
  • Loading branch information
Cyrix126 committed Oct 10, 2024
1 parent ee3fcce commit 5230d46
Show file tree
Hide file tree
Showing 36 changed files with 756 additions and 710 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/lockbud.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Lockbud

on: push

jobs:
test:
name: lockbud
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Generate code coverage
run: |
git clone https://github.com/BurtonQin/lockbud.git
cd lockbud
cargo install --path .
cd ..
cargo clean
cargo lockbud -k deadlock -l gupaxx &> >(tee log.out)
if grep -q "WARN" log.out; then
echo "Lockbud warnings found:"
echo "$output"
exit 1
fi
4 changes: 2 additions & 2 deletions rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[toolchain]
channel = "nightly-2024-07-24"
components = [ "rustfmt", "rustc-dev", "cargo", "clippy", "rust-analyzer"]
channel = "nightly-2024-10-05"
components = [ "rustfmt", "rustc-dev", "cargo", "clippy", "rust-analyzer", "rust-src", "llvm-tools-preview"]
target = ["x86_64-unknown-linux-gnu", "aarch64-apple-darwin", "x86_64-apple-darwin","x86_64-pc-windows-gnu"]
13 changes: 6 additions & 7 deletions src/app/eframe_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use crate::errors::{process_running, ErrorButtons, ErrorFerris};
#[cfg(target_os = "windows")]
use crate::helper::ProcessName;
use crate::helper::ProcessState;
use crate::macros::lock;
use crate::SECOND;
use egui::CentralPanel;
use log::debug;
Expand All @@ -29,31 +28,31 @@ impl eframe::App for App {
// might as well check only once here to save
// on a bunch of [.lock().unwrap()]s.
debug!("App | Locking and collecting P2Pool state...");
let p2pool = lock!(self.p2pool);
let p2pool = self.p2pool.lock().unwrap();
let p2pool_is_alive = p2pool.is_alive();
let p2pool_is_waiting = p2pool.is_waiting();
let p2pool_state = p2pool.state;
drop(p2pool);
debug!("App | Locking and collecting XMRig state...");
let xmrig = lock!(self.xmrig);
let xmrig = self.xmrig.lock().unwrap();
let xmrig_is_alive = xmrig.is_alive();
let xmrig_is_waiting = xmrig.is_waiting();
let xmrig_state = xmrig.state;
drop(xmrig);
debug!("App | Locking and collecting XMRig-Proxy state...");
let xmrig_proxy = lock!(self.xmrig_proxy);
let xmrig_proxy = self.xmrig_proxy.lock().unwrap();
let xmrig_proxy_is_alive = xmrig_proxy.is_alive();
let xmrig_proxy_is_waiting = xmrig_proxy.is_waiting();
let xmrig_proxy_state = xmrig_proxy.state;
drop(xmrig_proxy);
debug!("App | Locking and collecting XvB state...");
let xvb = lock!(self.xvb);
let xvb = self.xvb.lock().unwrap();
let xvb_is_alive = xvb.is_alive();
let xvb_is_waiting = xvb.is_waiting();
let xvb_state = xvb.state;
drop(xvb);
debug!("App | Locking and collecting Node state...");
let node = lock!(self.node);
let node = self.node.lock().unwrap();
let node_is_alive = node.is_alive();
let node_is_waiting = node.is_waiting();
let node_state = node.state;
Expand Down Expand Up @@ -94,7 +93,7 @@ impl eframe::App for App {
// contains Arc<Mutex>'s that cannot be compared easily.
// They don't need to be compared anyway.
debug!("App | Checking diff between [og] & [state]");
let og = lock!(self.og);
let og = self.og.lock().unwrap();
self.diff = og.status != self.state.status
|| og.gupax != self.state.gupax
|| og.node != self.state.node
Expand Down
22 changes: 12 additions & 10 deletions src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ use crate::miscs::get_exe;
use crate::miscs::get_exe_dir;
use crate::utils::constants::VISUALS;
use crate::utils::macros::arc_mut;
use crate::utils::macros::lock;
use crate::utils::sudo::SudoState;
use crate::APP_DEFAULT_HEIGHT;
use crate::APP_DEFAULT_WIDTH;
Expand Down Expand Up @@ -371,7 +370,10 @@ impl App {
app.pool_path.push(POOL_TOML);
// Set GupaxP2poolApi path
app.gupax_p2pool_api_path = crate::disk::get_gupax_p2pool_path(&app.os_data_path);
lock!(app.gupax_p2pool_api).fill_paths(&app.gupax_p2pool_api_path);
app.gupax_p2pool_api
.lock()
.unwrap()
.fill_paths(&app.gupax_p2pool_api_path);

// Apply arg state
// It's not safe to [--reset] if any of the previous variables
Expand Down Expand Up @@ -453,7 +455,7 @@ impl App {

//----------------------------------------------------------------------------------------------------
// Read [GupaxP2poolApi] disk files
let mut gupax_p2pool_api = lock!(app.gupax_p2pool_api);
let mut gupax_p2pool_api = app.gupax_p2pool_api.lock().unwrap();
match GupaxP2poolApi::create_all_files(&app.gupax_p2pool_api_path) {
Ok(_) => info!("App Init | Creating Gupax-P2Pool API files ... OK"),
Err(err) => {
Expand Down Expand Up @@ -493,11 +495,11 @@ impl App {
}
};
drop(gupax_p2pool_api);
lock!(app.helper).gupax_p2pool_api = Arc::clone(&app.gupax_p2pool_api);
app.helper.lock().unwrap().gupax_p2pool_api = Arc::clone(&app.gupax_p2pool_api);

//----------------------------------------------------------------------------------------------------
let mut og = lock!(app.og); // Lock [og]
// Handle max threads
let mut og = app.og.lock().unwrap(); // Lock [og]
// Handle max threads
info!("App Init | Handling max thread overflow...");
og.xmrig.max_threads = app.max_threads;
let current = og.xmrig.current_threads;
Expand Down Expand Up @@ -585,8 +587,8 @@ impl App {

// Set state version as compiled in version
info!("App Init | Setting state Gupax version...");
lock!(og.version).gupax = GUPAX_VERSION.to_string();
lock!(app.state.version).gupax = GUPAX_VERSION.to_string();
og.version.lock().unwrap().gupax = GUPAX_VERSION.to_string();
app.state.version.lock().unwrap().gupax = GUPAX_VERSION.to_string();

// Set saved [Tab]
info!("App Init | Setting saved [Tab]...");
Expand Down Expand Up @@ -660,7 +662,7 @@ impl App {
// Realistically, most of them are, but we can't be sure,
// and checking here without explicitly asking the user
// to connect to nodes is a no-go (also, non-async environment).
if !lock!(self.ping).pinged {
if !self.ping.lock().unwrap().pinged {
warn!("Backup hosts ... simple node backup: no ping data available, returning None");
return None;
}
Expand All @@ -670,7 +672,7 @@ impl App {

// Locking during this entire loop should be fine,
// only a few nodes to iter through.
for pinged_node in lock!(self.ping).nodes.iter() {
for pinged_node in self.ping.lock().unwrap().nodes.iter() {
// Continue if this node is not green/yellow.
if pinged_node.ms > crate::components::node::RED_NODE_PING {
continue;
Expand Down
29 changes: 14 additions & 15 deletions src/app/panels/bottom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use crate::errors::process_running;
use crate::helper::{Helper, ProcessSignal, ProcessState};
use crate::utils::constants::*;
use crate::utils::errors::{ErrorButtons, ErrorFerris};
use crate::utils::macros::lock;
use crate::utils::regex::Regexes;
use egui::TextStyle::Name;
use egui::*;
Expand Down Expand Up @@ -52,7 +51,7 @@ impl crate::app::App {
let size = vec2(0.0, height);
// [Gupax Version]
// Is yellow if the user updated and should (but isn't required to) restart.
match *lock!(self.restart) {
match *self.restart.lock().unwrap() {
Restart::Yes => ui
.add_sized(
size,
Expand Down Expand Up @@ -174,7 +173,7 @@ impl crate::app::App {
.on_hover_text("Reset changes")
.clicked()
{
let og = lock!(self.og).clone();
let og = self.og.lock().unwrap().clone();
self.state.status = og.status;
self.state.gupax = og.gupax;
self.state.node = og.node;
Expand All @@ -193,7 +192,7 @@ impl crate::app::App {
{
match State::save(&mut self.state, &self.state_path) {
Ok(_) => {
let mut og = lock!(self.og);
let mut og = self.og.lock().unwrap();
og.status = self.state.status.clone();
og.gupax = self.state.gupax.clone();
og.node = self.state.node.clone();
Expand Down Expand Up @@ -380,7 +379,7 @@ impl crate::app::App {
.on_hover_text("Restart P2Pool")
.clicked()
{
let _ = lock!(self.og).update_absolute_path();
let _ = self.og.lock().unwrap().update_absolute_path();
let _ = self.state.update_absolute_path();
Helper::restart_p2pool(
&self.helper,
Expand Down Expand Up @@ -435,7 +434,7 @@ impl crate::app::App {
.on_disabled_hover_text(text)
.clicked()
{
let _ = lock!(self.og).update_absolute_path();
let _ = self.og.lock().unwrap().update_absolute_path();
let _ = self.state.update_absolute_path();
Helper::start_p2pool(
&self.helper,
Expand Down Expand Up @@ -476,7 +475,7 @@ impl crate::app::App {
.on_hover_text("Restart node")
.clicked()
{
let _ = lock!(self.og).update_absolute_path();
let _ = self.og.lock().unwrap().update_absolute_path();
let _ = self.state.update_absolute_path();
Helper::restart_node(
&self.helper,
Expand Down Expand Up @@ -525,7 +524,7 @@ impl crate::app::App {
.on_disabled_hover_text(text)
.clicked()
{
let _ = lock!(self.og).update_absolute_path();
let _ = self.og.lock().unwrap().update_absolute_path();
let _ = self.state.update_absolute_path();
Helper::start_node(
&self.helper,
Expand Down Expand Up @@ -619,7 +618,7 @@ impl crate::app::App {
.on_hover_text("Restart XMRig")
.clicked()
{
let _ = lock!(self.og).update_absolute_path();
let _ = self.og.lock().unwrap().update_absolute_path();
let _ = self.state.update_absolute_path();
if cfg!(windows) {
Helper::restart_xmrig(
Expand All @@ -629,7 +628,7 @@ impl crate::app::App {
Arc::clone(&self.sudo),
);
} else {
lock!(self.sudo).signal = ProcessSignal::Restart;
self.sudo.lock().unwrap().signal = ProcessSignal::Restart;
self.error_state.ask_sudo(&self.sudo);
}
}
Expand All @@ -640,7 +639,7 @@ impl crate::app::App {
.clicked()
{
if cfg!(target_os = "macos") {
lock!(self.sudo).signal = ProcessSignal::Stop;
self.sudo.lock().unwrap().signal = ProcessSignal::Stop;
self.error_state.ask_sudo(&self.sudo);
} else {
Helper::stop_xmrig(&self.helper);
Expand Down Expand Up @@ -679,7 +678,7 @@ impl crate::app::App {
.on_disabled_hover_text(text)
.clicked()
{
let _ = lock!(self.og).update_absolute_path();
let _ = self.og.lock().unwrap().update_absolute_path();
let _ = self.state.update_absolute_path();
if cfg!(windows) {
Helper::start_xmrig(
Expand All @@ -689,7 +688,7 @@ impl crate::app::App {
Arc::clone(&self.sudo),
);
} else if cfg!(unix) {
lock!(self.sudo).signal = ProcessSignal::Start;
self.sudo.lock().unwrap().signal = ProcessSignal::Start;
self.error_state.ask_sudo(&self.sudo);
}
}
Expand Down Expand Up @@ -829,7 +828,7 @@ impl crate::app::App {
.on_hover_text("Restart XMRig-Proxy")
.clicked()
{
let _ = lock!(self.og).update_absolute_path();
let _ = self.og.lock().unwrap().update_absolute_path();
let _ = self.state.update_absolute_path();
Helper::restart_xp(
&self.helper,
Expand Down Expand Up @@ -881,7 +880,7 @@ impl crate::app::App {
.on_disabled_hover_text(text)
.clicked()
{
let _ = lock!(self.og).update_absolute_path();
let _ = self.og.lock().unwrap().update_absolute_path();
let _ = self.state.update_absolute_path();
Helper::start_xp(
&self.helper,
Expand Down
25 changes: 17 additions & 8 deletions src/app/panels/middle/gupax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use crate::app::Restart;
use crate::components::gupax::*;
use crate::components::update::Update;
use crate::disk::state::*;
use crate::macros::lock2;
use log::debug;
use std::path::Path;
use std::sync::Arc;
Expand Down Expand Up @@ -40,7 +39,7 @@ impl Gupax {
size.y / 10.0
};
let width = size.x - SPACE;
let updating = *lock2!(update, updating);
let updating = *update.lock().unwrap().updating.lock().unwrap();
ui.vertical(|ui| {
// If [Gupax] is being built for a Linux distro,
// disable built-in updating completely.
Expand All @@ -50,7 +49,7 @@ impl Gupax {
ui.add_sized([width, button], Button::new("Updates are disabled"))
.on_disabled_hover_text(DISTRO_NO_UPDATE);
#[cfg(not(feature = "distro"))]
ui.add_enabled_ui(!updating && *lock!(restart) == Restart::No, |ui| {
ui.add_enabled_ui(!updating && *restart.lock().unwrap() == Restart::No, |ui| {
#[cfg(not(feature = "distro"))]
if ui
.add_sized([width, button], Button::new("Check for updates"))
Expand All @@ -70,8 +69,13 @@ impl Gupax {
});
ui.vertical(|ui| {
ui.add_enabled_ui(updating, |ui| {
let prog = *lock2!(update, prog);
let msg = format!("{}\n{}{}", *lock2!(update, msg), prog, "%");
let prog = *update.lock().unwrap().prog.lock().unwrap();
let msg = format!(
"{}\n{}{}",
*update.lock().unwrap().msg.lock().unwrap(),
prog,
"%"
);
ui.add_sized([width, height * 1.4], Label::new(RichText::new(msg)));
let height = height / 2.0;
let size = vec2(width, height);
Expand All @@ -80,7 +84,12 @@ impl Gupax {
} else {
ui.add_sized(size, Label::new("..."));
}
ui.add_sized(size, ProgressBar::new(lock2!(update, prog).round() / 100.0));
ui.add_sized(
size,
ProgressBar::new(
update.lock().unwrap().prog.lock().unwrap().round() / 100.0,
),
);
});
});
});
Expand Down Expand Up @@ -140,7 +149,7 @@ impl Gupax {
debug!("Gupaxx Tab | Rendering P2Pool/XMRig path selection");
// P2Pool/XMRig binary path selection
// need to clone bool so file_window is not locked across a thread
let window_busy = lock!(file_window).thread.to_owned();
let window_busy = file_window.lock().unwrap().thread.to_owned();
let height = size.y / 28.0;
let text_edit = (ui.available_width() / 10.0) - SPACE;
ui.group(|ui| {
Expand Down Expand Up @@ -309,7 +318,7 @@ impl Gupax {
});
});
});
let mut guard = lock!(file_window);
let mut guard = file_window.lock().unwrap();
if guard.picked_p2pool {
self.p2pool_path.clone_from(&guard.p2pool_path);
guard.picked_p2pool = false;
Expand Down
Loading

0 comments on commit 5230d46

Please sign in to comment.