feat: add deadlock detection at CI
Some checks are pending
CI / ci (macos-12) (push) Waiting to run
CI / ci (ubuntu-latest) (push) Waiting to run
Lockbud / lockbud (push) Waiting to run
Rust / fmt (push) Waiting to run
Rust / test (macos-latest) (push) Waiting to run
Rust / test (ubuntu-latest) (push) Waiting to run
Rust / typo (push) Waiting to run
Rust / clippy (macos-latest) (push) Waiting to run
Rust / clippy (ubuntu-latest) (push) Waiting to run
Rust / check (macos-latest) (push) Waiting to run
Rust / check (ubuntu-latest) (push) Waiting to run
Rust / doc (macos-latest) (push) Waiting to run
Rust / doc (ubuntu-latest) (push) Waiting to run
Typo / typo (push) Waiting to run

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()'{}
`
This commit is contained in:
Cyrix126 2024-10-10 16:42:27 +02:00
parent ee3fcce0d8
commit 5230d46d93
36 changed files with 756 additions and 710 deletions

25
.github/workflows/lockbud.yml vendored Normal file
View file

@ -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

View file

@ -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"]

View file

@ -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;
@ -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;
@ -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

View file

@ -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;
@ -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
@ -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) => {
@ -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;
@ -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]...");
@ -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;
}
@ -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;

View file

@ -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::*;
@ -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,
@ -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;
@ -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();
@ -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,
@ -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,
@ -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,
@ -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,
@ -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(
@ -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);
}
}
@ -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);
@ -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(
@ -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);
}
}
@ -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,
@ -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,

View file

@ -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;
@ -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.
@ -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"))
@ -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);
@ -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,
),
);
});
});
});
@ -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| {
@ -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;

View file

@ -3,7 +3,6 @@ use crate::app::Tab;
use crate::helper::ProcessState;
use crate::utils::constants::*;
use crate::utils::errors::{ErrorButtons, ErrorFerris};
use crate::utils::macros::lock;
use egui::*;
use log::debug;
@ -44,10 +43,10 @@ impl crate::app::App {
let distro = true;
#[cfg(not(feature = "distro"))]
let distro = false;
let p2pool_gui_len = lock!(self.p2pool_api).output.len();
let xmrig_gui_len = lock!(self.xmrig_api).output.len();
let xmrig_proxy_gui_len = lock!(self.xmrig_proxy_api).output.len();
let gupax_p2pool_api = lock!(self.gupax_p2pool_api);
let p2pool_gui_len = self.p2pool_api.lock().unwrap().output.len();
let xmrig_gui_len = self.xmrig_api.lock().unwrap().output.len();
let xmrig_proxy_gui_len = self.xmrig_proxy_api.lock().unwrap().output.len();
let gupax_p2pool_api = self.gupax_p2pool_api.lock().unwrap();
let debug_info = format!(
"Gupax version: {}\n
Bundled P2Pool version: {}\n
@ -118,8 +117,8 @@ path_xmr: {:#?}\n
p2pool_gui_len,
xmrig_gui_len,
xmrig_proxy_gui_len,
lock!(self.p2pool_img),
lock!(self.xmrig_img),
self.p2pool_img.lock().unwrap(),
self.xmrig_img.lock().unwrap(),
gupax_p2pool_api.payout,
gupax_p2pool_api.payout_u64,
gupax_p2pool_api.xmr,
@ -127,7 +126,7 @@ path_xmr: {:#?}\n
gupax_p2pool_api.path_payout,
gupax_p2pool_api.path_xmr,
self.state,
lock!(self.og),
self.og.lock().unwrap(),
);
self.error_state.set(debug_info, ErrorFerris::Cute, ErrorButtons::Debug);
}
@ -153,7 +152,7 @@ path_xmr: {:#?}\n
ui.add_space(SPACE*2.0);
if cfg!(debug_assertions) { ui.label(format!("Gupax is running in debug mode - {}", self.now.elapsed().as_secs_f64())); }
ui.label(format!("Gupax has been running for {}", lock!(self.pub_sys).gupax_uptime));
ui.label(format!("Gupax has been running for {}", self.pub_sys.lock().unwrap().gupax_uptime));
});
}
Tab::Status => {
@ -182,7 +181,7 @@ path_xmr: {:#?}\n
}
Tab::Xvb => {
debug!("App | Entering [XvB] Tab");
crate::disk::state::Xvb::show(&mut self.state.xvb, self.size, &self.state.p2pool.address, ctx, ui, &self.xvb_api, &self.xmrig_api, lock!(self.xvb).state == ProcessState::Alive);
crate::disk::state::Xvb::show(&mut self.state.xvb, self.size, &self.state.p2pool.address, ctx, ui, &self.xvb_api, &self.xmrig_api, self.xvb.lock().unwrap().state == ProcessState::Alive);
}
}
});

View file

@ -16,7 +16,6 @@ use crate::helper::node::PubNodeApi;
use crate::helper::Process;
use crate::regex::{num_lines, REGEXES};
use crate::utils::constants::DARK_GRAY;
use crate::utils::macros::lock;
use crate::{GREEN, LIGHT_GRAY, P2POOL_IN, P2POOL_LOG, P2POOL_OUT, RED, SPACE};
impl Node {
@ -47,7 +46,7 @@ impl Node {
// console output for log
debug!("Node Tab | Rendering [Console]");
ui.group(|ui| {
let text = &lock!(api).output;
let text = &api.lock().unwrap().output;
let nb_lines = num_lines(text);
let height = size.y / 2.8;
let width = size.x - (space_h / 2.0);
@ -89,7 +88,7 @@ impl Node {
if response.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter)) {
response.request_focus(); // Get focus back
let buffer = std::mem::take(buffer); // Take buffer
let mut process = lock!(process); // Lock
let mut process = process.lock().unwrap(); // Lock
if process.is_alive() {
process.input.push(buffer);
} // Push only if alive
@ -326,7 +325,7 @@ fn path_db_field(
);
ui.spacing_mut().text_edit_width =
ui.available_width() - (ui.spacing().item_spacing.x * 8.0) - SPACE * 2.0;
let window_busy = lock!(file_window).thread;
let window_busy = file_window.lock().unwrap().thread;
ui.add_enabled_ui(!window_busy, |ui| {
if ui.button("Open").on_hover_text(GUPAX_SELECT).clicked() {
Gupax::spawn_file_window_thread(file_window, FileType::NodeDB);
@ -336,7 +335,7 @@ fn path_db_field(
});
});
let mut guard = lock!(file_window);
let mut guard = file_window.lock().unwrap();
if guard.picked_nodedb {
state.path_db.clone_from(&guard.nodedb_path);
guard.picked_nodedb = false;

View file

@ -18,7 +18,7 @@ use crate::regex::num_lines;
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use crate::{components::node::*, constants::*, helper::*, macros::*, utils::regex::Regexes};
use crate::{components::node::*, constants::*, helper::*, utils::regex::Regexes};
use egui::{
vec2, Color32, Label, RichText, TextEdit,
TextStyle::{self, *},
@ -53,7 +53,7 @@ impl P2pool {
// debug!("P2Pool Tab | Rendering [Console]");
egui::ScrollArea::vertical().show(ui, |ui| {
ui.group(|ui| {
let text = &lock!(api).output;
let text = &api.lock().unwrap().output;
let nb_lines = num_lines(text);
let (height, width) = if self.simple {
((size.y * 0.38) - SPACE, size.x - SPACE)
@ -104,7 +104,7 @@ impl P2pool {
if response.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter)) {
response.request_focus(); // Get focus back
let buffer = std::mem::take(buffer); // Take buffer
let mut process = lock!(process); // Lock
let mut process = process.lock().unwrap(); // Lock
if process.is_alive() {
process.input.push(buffer);
} // Push only if alive

View file

@ -9,7 +9,6 @@ use crate::components::node::format_ms;
use crate::components::node::Ping;
use crate::components::node::RemoteNode;
use crate::disk::state::P2pool;
use crate::utils::macros::lock;
use egui::vec2;
use egui::Button;
use egui::Checkbox;
@ -47,7 +46,7 @@ impl P2pool {
let visible = !self.local_node;
debug!("P2Pool Tab | Running [auto-select] check");
if self.auto_select && visible {
let mut ping = lock!(ping);
let mut ping = ping.lock().unwrap();
// If we haven't auto_selected yet, auto-select and turn it off
if ping.pinged && !ping.auto_selected {
self.node = ping.fastest.to_string();
@ -63,8 +62,8 @@ impl P2pool {
// [Ping List]
let mut ms = 0;
let mut color = Color32::LIGHT_GRAY;
if lock!(ping).pinged {
for data in lock!(ping).nodes.iter() {
if ping.lock().unwrap().pinged {
for data in ping.lock().unwrap().nodes.iter() {
if data.ip == self.node {
ms = data.ms;
color = data.color;
@ -79,7 +78,7 @@ impl P2pool {
.selected_text(text)
.width(size.x)
.show_ui(ui, |ui| {
for data in lock!(ping).nodes.iter() {
for data in ping.lock().unwrap().nodes.iter() {
let ms = format_ms(data.ms);
let ip_location = format_ip_location(data.ip, true);
let text = RichText::new(format!("{} | {}", ms, ip_location))
@ -108,12 +107,12 @@ impl P2pool {
.add_sized(size, Button::new("Select fastest node"))
.on_hover_text(P2POOL_SELECT_FASTEST)
.clicked()
&& lock!(ping).pinged
&& ping.lock().unwrap().pinged
{
self.node = lock!(ping).fastest.to_string();
self.node = ping.lock().unwrap().fastest.to_string();
}
// [Ping Button]
ui.add_enabled_ui(!lock!(ping).pinging, |ui| {
ui.add_enabled_ui(!ping.lock().unwrap().pinging, |ui| {
if ui
.add_sized(size, Button::new("Ping remote nodes"))
.on_hover_text(P2POOL_PING)
@ -128,7 +127,7 @@ impl P2pool {
.on_hover_text(P2POOL_SELECT_LAST)
.clicked()
{
let ping = lock!(ping);
let ping = ping.lock().unwrap();
match ping.pinged {
true => {
self.node = RemoteNode::get_last_from_ping(&self.node, &ping.nodes)
@ -143,7 +142,7 @@ impl P2pool {
.on_hover_text(P2POOL_SELECT_NEXT)
.clicked()
{
let ping = lock!(ping);
let ping = ping.lock().unwrap();
match ping.pinged {
true => {
self.node = RemoteNode::get_next_from_ping(&self.node, &ping.nodes)
@ -156,10 +155,11 @@ impl P2pool {
ui.vertical(|ui| {
let height = height / 2.0;
let pinging = lock!(ping).pinging;
let pinging = ping.lock().unwrap().pinging;
ui.add_enabled_ui(pinging, |ui| {
let prog = lock!(ping).prog.round();
let msg = RichText::new(format!("{} ... {}%", lock!(ping).msg, prog));
let prog = ping.lock().unwrap().prog.round();
let msg =
RichText::new(format!("{} ... {}%", ping.lock().unwrap().msg, prog));
let height = height / 1.25;
let size = vec2(size.x, height);
ui.add_space(space_h);

View file

@ -5,8 +5,6 @@ use egui::{Hyperlink, ProgressBar, ScrollArea, Spinner, Vec2};
use egui_extras::{Column, TableBuilder};
use readable::num::{Float, Percent, Unsigned};
use crate::utils::macros::lock;
use crate::constants::*;
use egui::{Label, RichText};
use log::*;
@ -93,7 +91,7 @@ impl Status {
// User's CPU hashrate comparison (if XMRig is alive).
ui.scope(|ui| {
if xmrig_alive {
let api = lock!(xmrig_api);
let api = xmrig_api.lock().unwrap();
let percent = (api.hashrate_raw / cpu.high) * 100.0;
let human = Percent::from(percent);
if percent > 100.0 {

View file

@ -10,7 +10,7 @@ use crate::{
status::{Hash, PayoutView},
},
helper::p2pool::PubP2poolApi,
utils::{constants::*, macros::lock},
utils::constants::*,
};
impl Status {
@ -22,7 +22,7 @@ impl Status {
p2pool_alive: bool,
p2pool_api: &Arc<Mutex<PubP2poolApi>>,
) {
let api = lock!(gupax_p2pool_api);
let api = gupax_p2pool_api.lock().unwrap();
let height = size.y;
let width = size.x;
let text = height / 25.0;
@ -214,7 +214,7 @@ impl Status {
let text = height / 25.0;
let width = (width / 3.0) - (SPACE * 1.666);
let min_height = ui.available_height() / 1.3;
let api = lock!(p2pool_api);
let api = p2pool_api.lock().unwrap();
ui.horizontal(|ui| {
ui.group(|ui| {
ui.vertical(|ui| {

View file

@ -9,7 +9,6 @@ use crate::helper::xrig::xmrig::{ImgXmrig, PubXmrigApi};
use crate::helper::xrig::xmrig_proxy::PubXmrigProxyApi;
use crate::helper::xvb::{rounds::XvbRound, PubXvbApi};
use crate::helper::Sys;
use crate::utils::macros::lock;
use egui::TextStyle;
use crate::constants::*;
@ -91,7 +90,7 @@ fn gupax(ui: &mut Ui, min_size: Vec2, size: Vec2, sys: &Arc<Mutex<Sys>>) {
),
)
.on_hover_text("Gupaxx is online");
let sys = lock!(sys);
let sys = sys.lock().unwrap();
ui.add_sized(
size,
Label::new(RichText::new("Uptime").underline().color(BONE)),
@ -160,7 +159,7 @@ fn p2pool(
.on_disabled_hover_text("P2Pool is offline");
ui.style_mut().override_text_style = Some(Name("MonospaceSmall".into()));
let size = [size.x, size.y / 1.4];
let api = lock!(p2pool_api);
let api = p2pool_api.lock().unwrap();
ui.add_sized(
size,
Label::new(RichText::new("Uptime").underline().color(BONE)),
@ -249,7 +248,7 @@ fn p2pool(
api.average_effort, api.current_effort
)),
);
let img = lock!(p2pool_img);
let img = p2pool_img.lock().unwrap();
ui.add_sized(
size,
Label::new(RichText::new("Monero Node").underline().color(BONE)),
@ -305,7 +304,7 @@ fn xmrig_proxy(
)
.on_hover_text("XMRig-Proxy is online")
.on_disabled_hover_text("XMRig-Proxy is offline");
let api = lock!(xmrig_proxy_api);
let api = xmrig_proxy_api.lock().unwrap();
ui.add_sized(
size,
Label::new(RichText::new("Uptime").underline().color(BONE)),
@ -378,7 +377,7 @@ fn xmrig(
)
.on_hover_text("XMRig is online")
.on_disabled_hover_text("XMRig is offline");
let api = lock!(xmrig_api);
let api = xmrig_api.lock().unwrap();
ui.add_sized(
size,
Label::new(RichText::new("Uptime").underline().color(BONE)),
@ -427,7 +426,11 @@ fn xmrig(
.on_hover_text(STATUS_XMRIG_THREADS);
ui.add_sized(
size,
Label::new(format!("{}/{}", &lock!(xmrig_img).threads, max_threads)),
Label::new(format!(
"{}/{}",
&xmrig_img.lock().unwrap().threads,
max_threads
)),
);
drop(api);
});
@ -438,7 +441,7 @@ fn xmrig(
fn xvb(ui: &mut Ui, min_size: Vec2, size: Vec2, xvb_alive: bool, xvb_api: &Arc<Mutex<PubXvbApi>>) {
//
let api = &lock!(xvb_api).stats_pub;
let api = &xvb_api.lock().unwrap().stats_pub;
let enabled = xvb_alive;
ui.group(|ui| {
ScrollArea::vertical().show(ui, |ui| {
@ -583,7 +586,7 @@ fn node(
)
.on_hover_text("Node is online")
.on_disabled_hover_text("Node is offline");
let api = lock!(node_api);
let api = node_api.lock().unwrap();
ui.add_sized(
size,
Label::new(RichText::new("Uptime").underline().color(BONE)),

View file

@ -15,13 +15,13 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use crate::constants::*;
use crate::disk::pool::Pool;
use crate::disk::state::Xmrig;
use crate::helper::xrig::xmrig::PubXmrigApi;
use crate::helper::Process;
use crate::regex::{num_lines, REGEXES};
use crate::utils::regex::Regexes;
use crate::{constants::*, macros::*};
use egui::{
vec2, Button, Checkbox, ComboBox, Label, RichText, SelectableLabel, Slider, TextEdit,
TextStyle::{self, *},
@ -49,7 +49,7 @@ impl Xmrig {
debug!("XMRig Tab | Rendering [Console]");
egui::ScrollArea::vertical().show(ui, |ui| {
ui.group(|ui| {
let text = &lock!(api).output;
let text = &api.lock().unwrap().output;
let nb_lines = num_lines(text);
let (height, width) = if self.simple {
(size.y / 1.5, size.x - SPACE)
@ -93,7 +93,7 @@ impl Xmrig {
if response.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter)) {
response.request_focus(); // Get focus back
let buffer = std::mem::take(buffer); // Take buffer
let mut process = lock!(process); // Lock
let mut process = process.lock().unwrap(); // Lock
if process.is_alive() {
process.input.push(buffer);
} // Push only if alive

View file

@ -10,7 +10,6 @@ use crate::helper::xrig::xmrig_proxy::PubXmrigProxyApi;
use crate::helper::Process;
use crate::regex::{num_lines, REGEXES};
use crate::utils::constants::DARK_GRAY;
use crate::utils::macros::lock;
use crate::{
GREEN, LIGHT_GRAY, LIST_ADD, LIST_CLEAR, LIST_DELETE, LIST_SAVE, RED, SPACE, XMRIG_API_IP,
XMRIG_API_PORT, XMRIG_IP, XMRIG_KEEPALIVE, XMRIG_NAME, XMRIG_PORT, XMRIG_PROXY_ARGUMENTS,
@ -44,7 +43,7 @@ impl XmrigProxy {
// console output for log
debug!("Xmrig-Proxy Tab | Rendering [Console]");
ui.group(|ui| {
let text = &lock!(api).output;
let text = &api.lock().unwrap().output;
let nb_lines = num_lines(text);
let height = size.y / 2.8;
let width = size.x - (space_h / 2.0);
@ -86,7 +85,7 @@ impl XmrigProxy {
if response.lost_focus() && ui.input(|i| i.key_pressed(egui::Key::Enter)) {
response.request_focus(); // Get focus back
let buffer = std::mem::take(buffer); // Take buffer
let mut process = lock!(process); // Lock
let mut process = process.lock().unwrap(); // Lock
if process.is_alive() {
process.input.push(buffer);
} // Push only if alive

View file

@ -20,7 +20,6 @@ use crate::utils::constants::{
XVB_MODE_MANUAL_P2POOL_HELP, XVB_MODE_MANUAL_XVB_HELP, XVB_ROUND_TYPE_FIELD, XVB_TOKEN_FIELD,
XVB_TOKEN_LEN, XVB_URL_RULES, XVB_WINNER_FIELD,
};
use crate::utils::macros::lock;
use crate::utils::regex::Regexes;
use crate::XVB_MINING_ON_FIELD;
use crate::{
@ -64,7 +63,7 @@ impl crate::disk::state::Xvb {
// console output for log
debug!("XvB Tab | Rendering [Console]");
ui.group(|ui| {
let text = &lock!(api).output;
let text = &api.lock().unwrap().output;
let nb_lines = num_lines(text);
let height = size.y / 2.8;
let width = size.x - (space_h / 2.0);
@ -134,9 +133,9 @@ impl crate::disk::state::Xvb {
if ui.checkbox(&mut self.simple_hero_mode, "Hero Mode").on_hover_text(XVB_HERO_SELECT).clicked() {
// also change hero mode of runtime.
lock!(api).stats_priv.runtime_mode = RuntimeMode::Hero;
api.lock().unwrap().stats_priv.runtime_mode = RuntimeMode::Hero;
} else {
lock!(api).stats_priv.runtime_mode = RuntimeMode::Auto;
api.lock().unwrap().stats_priv.runtime_mode = RuntimeMode::Auto;
}
}
@ -179,12 +178,12 @@ impl crate::disk::state::Xvb {
};
let mut hashrate_xmrig = {
if lock!(gui_api_xmrig).hashrate_raw_15m > 0.0 {
lock!(gui_api_xmrig).hashrate_raw_15m
} else if lock!(gui_api_xmrig).hashrate_raw_1m > 0.0 {
lock!(gui_api_xmrig).hashrate_raw_1m
} else if lock!(gui_api_xmrig).hashrate_raw > 0.0 {
lock!(gui_api_xmrig).hashrate_raw
if gui_api_xmrig.lock().unwrap().hashrate_raw_15m > 0.0 {
gui_api_xmrig.lock().unwrap().hashrate_raw_15m
} else if gui_api_xmrig.lock().unwrap().hashrate_raw_1m > 0.0 {
gui_api_xmrig.lock().unwrap().hashrate_raw_1m
} else if gui_api_xmrig.lock().unwrap().hashrate_raw > 0.0 {
gui_api_xmrig.lock().unwrap().hashrate_raw
} else {
default_xmrig_hashrate
}
@ -243,7 +242,7 @@ impl crate::disk::state::Xvb {
ManualDonationLevel::DonorMega.to_string())
.on_hover_text(XVB_DONATION_LEVEL_MEGA_DONOR_HELP);
lock!(api).stats_priv.runtime_manual_donation_level = self.manual_donation_level.clone().into();
api.lock().unwrap().stats_priv.runtime_manual_donation_level = self.manual_donation_level.clone().into();
}
});
});
@ -263,8 +262,8 @@ impl crate::disk::state::Xvb {
}
// Set runtime_mode & runtime_manual_amount
lock!(api).stats_priv.runtime_mode = self.mode.clone().into();
lock!(api).stats_priv.runtime_manual_amount = self.manual_amount_raw;
api.lock().unwrap().stats_priv.runtime_mode = self.mode.clone().into();
api.lock().unwrap().stats_priv.runtime_manual_amount = self.manual_amount_raw;
ui.add_space(space_h);
// allow user to modify the buffer for p2pool
@ -289,7 +288,7 @@ impl crate::disk::state::Xvb {
ui.add_space(space_h);
// ui.add_enabled_ui(is_alive, |ui| {
ui.add_enabled_ui(is_alive, |ui| {
let api = &lock!(api);
let api = &api.lock().unwrap();
let priv_stats = &api.stats_priv;
let current_node = &api.current_node;
let width_stat = (ui.available_width() - SPACE * 4.0) / 5.0;

View file

@ -6,7 +6,7 @@ use crate::disk::state::State;
use crate::utils::constants::*;
use crate::utils::errors::ErrorState;
use crate::utils::ferris::*;
use crate::utils::macros::{arc_mut, flip, lock, lock2};
use crate::utils::macros::{arc_mut, flip};
use crate::utils::resets::{reset_nodes, reset_state};
use crate::utils::sudo::SudoState;
use egui::TextStyle::Name;
@ -53,7 +53,7 @@ impl crate::app::App {
match self.error_state.buttons {
StayQuit => {
let mut text = "".to_string();
if *lock2!(self.update, updating) {
if *self.update.lock().unwrap().updating.lock().unwrap() {
text = format!(
"{}\nUpdate is in progress...! Quitting may cause file corruption!",
text
@ -277,7 +277,7 @@ impl crate::app::App {
ErrorButtons::Sudo => {
let sudo_width = width / 10.0;
let height = ui.available_height() / 4.0;
let mut sudo = lock!(self.sudo);
let mut sudo = self.sudo.lock().unwrap();
let hide = sudo.hide;
if sudo.testing {
ui.add_sized([width, height], Spinner::new().size(height));

View file

@ -15,10 +15,7 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use crate::{
disk::state::*,
utils::macros::{arc_mut, lock},
};
use crate::{disk::state::*, utils::macros::arc_mut};
use log::*;
use serde::{Deserialize, Serialize};
use std::{
@ -111,7 +108,7 @@ impl Gupax {
NodeDB => "Node DB",
};
let file_window = file_window.clone();
lock!(file_window).thread = true;
file_window.lock().unwrap().thread = true;
thread::spawn(move || {
let path = match file_type {
NodeDB => rfd::FileDialog::new()
@ -125,31 +122,31 @@ impl Gupax {
info!("Gupaxx | Path selected for {} ... {}", name, path.display());
match file_type {
P2pool => {
lock!(file_window).p2pool_path = path.display().to_string();
lock!(file_window).picked_p2pool = true;
file_window.lock().unwrap().p2pool_path = path.display().to_string();
file_window.lock().unwrap().picked_p2pool = true;
}
Xmrig => {
lock!(file_window).xmrig_path = path.display().to_string();
lock!(file_window).picked_xmrig = true;
file_window.lock().unwrap().xmrig_path = path.display().to_string();
file_window.lock().unwrap().picked_xmrig = true;
}
XmrigProxy => {
lock!(file_window).xmrig_proxy_path = path.display().to_string();
lock!(file_window).picked_xp = true;
file_window.lock().unwrap().xmrig_proxy_path = path.display().to_string();
file_window.lock().unwrap().picked_xp = true;
}
Node => {
lock!(file_window).node_path = path.display().to_string();
lock!(file_window).picked_node = true;
file_window.lock().unwrap().node_path = path.display().to_string();
file_window.lock().unwrap().picked_node = true;
}
NodeDB => {
lock!(file_window).nodedb_path = path.display().to_string();
lock!(file_window).picked_nodedb = true;
file_window.lock().unwrap().nodedb_path = path.display().to_string();
file_window.lock().unwrap().picked_nodedb = true;
}
};
} else {
info!("Gupaxx | No path selected for {}", name);
}
lock!(file_window).thread = false;
file_window.lock().unwrap().thread = false;
});
}
}

View file

@ -331,19 +331,19 @@ impl Ping {
match Self::ping(&ping) {
Ok(msg) => {
info!("Ping ... OK");
lock!(ping).msg = msg;
lock!(ping).pinged = true;
lock!(ping).auto_selected = false;
lock!(ping).prog = 100.0;
ping.lock().unwrap().msg = msg;
ping.lock().unwrap().pinged = true;
ping.lock().unwrap().auto_selected = false;
ping.lock().unwrap().prog = 100.0;
}
Err(err) => {
error!("Ping ... FAIL ... {}", err);
lock!(ping).pinged = false;
lock!(ping).msg = err.to_string();
ping.lock().unwrap().pinged = false;
ping.lock().unwrap().msg = err.to_string();
}
}
info!("Ping ... Took [{}] seconds...", now.elapsed().as_secs_f32());
lock!(ping).pinging = false;
ping.lock().unwrap().pinging = false;
});
}
@ -370,13 +370,13 @@ impl Ping {
pub async fn ping(ping: &Arc<Mutex<Self>>) -> Result<String, anyhow::Error> {
// Start ping
let ping = Arc::clone(ping);
lock!(ping).pinging = true;
lock!(ping).prog = 0.0;
ping.lock().unwrap().pinging = true;
ping.lock().unwrap().prog = 0.0;
let percent = (100.0 / (REMOTE_NODE_LENGTH as f32)).floor();
// Create HTTP client
let info = "Creating HTTP Client".to_string();
lock!(ping).msg = info;
ping.lock().unwrap().msg = info;
let client = Client::new();
// Random User Agent
@ -404,13 +404,13 @@ impl Ping {
handle.await?;
}
let mut node_vec = std::mem::take(&mut *lock!(node_vec));
let mut node_vec = std::mem::take(&mut *node_vec.lock().unwrap());
node_vec.sort_by(|a, b| a.ms.cmp(&b.ms));
let fastest_info = format!("Fastest node: {}ms ... {}", node_vec[0].ms, node_vec[0].ip);
let info = "Cleaning up connections".to_string();
info!("Ping | {}...", info);
let mut ping = lock!(ping);
let mut ping = ping.lock().unwrap();
ping.fastest = node_vec[0].ip;
ping.nodes = node_vec;
ping.msg = info;
@ -467,11 +467,11 @@ impl Ping {
BLACK
};
let mut ping = lock!(ping);
let mut ping = ping.lock().unwrap();
ping.msg = info;
ping.prog += percent;
drop(ping);
lock!(node_vec).push(NodeData { ip, ms, color });
node_vec.lock().unwrap().push(NodeData { ip, ms, color });
}
}
//---------------------------------------------------------------------------------------------------- NODE

View file

@ -287,7 +287,7 @@ impl Update {
#[cfg(feature = "distro")]
return;
// verify validity of absolute path for p2pool, xmrig and xmrig-proxy only if we want to update them.
if lock!(og).gupax.bundled {
if og.lock().unwrap().gupax.bundled {
// Check P2Pool path for safety
// Attempt relative to absolute path
// it's ok if file doesn't exist. User could enable bundled version for the first time.
@ -350,15 +350,15 @@ impl Update {
return;
}
};
lock!(update).path_p2pool = p2pool_path.display().to_string();
lock!(update).path_xmrig = xmrig_path.display().to_string();
lock!(update).path_xp = xmrig_proxy_path.display().to_string();
lock!(update).path_node = node_path.display().to_string();
update.lock().unwrap().path_p2pool = p2pool_path.display().to_string();
update.lock().unwrap().path_xmrig = xmrig_path.display().to_string();
update.lock().unwrap().path_xp = xmrig_proxy_path.display().to_string();
update.lock().unwrap().path_node = node_path.display().to_string();
}
// Clone before thread spawn
let og = Arc::clone(og);
let state_ver = Arc::clone(&lock!(og).version);
let state_ver = Arc::clone(&og.lock().unwrap().version);
let state_path = state_path.to_path_buf();
let update = Arc::clone(update);
let restart = Arc::clone(restart);
@ -367,24 +367,25 @@ impl Update {
match Update::start(update.clone(), og.clone(), restart) {
Ok(_) => {
info!("Update | Saving state...");
let original_version = lock!(og).version.clone();
lock!(og).version = state_ver;
match State::save(&mut lock!(og), &state_path) {
let original_version = og.lock().unwrap().version.clone();
og.lock().unwrap().version = state_ver;
match State::save(&mut og.lock().unwrap(), &state_path) {
Ok(_) => info!("Update ... OK"),
Err(e) => {
warn!("Update | Saving state ... FAIL: {}", e);
lock!(og).version = original_version;
*lock2!(update, msg) =
og.lock().unwrap().version = original_version;
*update.lock().unwrap().msg.lock().unwrap() =
"Saving new versions into state failed".to_string();
}
};
}
Err(e) => {
info!("Update ... FAIL: {}", e);
*lock2!(update, msg) = format!("{} | {}\n{}", MSG_FAILED, e, MSG_FAILED_HELP);
*update.lock().unwrap().msg.lock().unwrap() =
format!("{} | {}\n{}", MSG_FAILED, e, MSG_FAILED_HELP);
}
};
*lock2!(update, updating) = false;
*update.lock().unwrap().updating.lock().unwrap() = false;
});
}
@ -412,38 +413,41 @@ impl Update {
));
//---------------------------------------------------------------------------------------------------- Init
*lock2!(update, updating) = true;
*update.lock().unwrap().updating.lock().unwrap() = true;
// Set timer
let now = std::time::Instant::now();
// Set progress bar
*lock2!(update, msg) = MSG_START.to_string();
*lock2!(update, prog) = 0.0;
*update.lock().unwrap().msg.lock().unwrap() = MSG_START.to_string();
*update.lock().unwrap().prog.lock().unwrap() = 0.0;
info!("Update | {}", INIT);
// Get temporary directory
let msg = MSG_TMP.to_string();
info!("Update | {}", msg);
*lock2!(update, msg) = msg;
*update.lock().unwrap().msg.lock().unwrap() = msg;
let tmp_dir = Self::get_tmp_dir()?;
std::fs::create_dir(&tmp_dir)?;
// Generate fake user-agent
let user_agent = get_user_agent();
*lock2!(update, prog) = 5.0;
*update.lock().unwrap().prog.lock().unwrap() = 5.0;
// Create HTTPS client
let lock = lock!(update);
let lock = update.lock().unwrap();
let msg = MSG_HTTPS.to_string();
info!("Update | {}", msg);
*lock!(lock.msg) = msg;
*lock.msg.lock().unwrap() = msg;
drop(lock);
let client = Client::new();
*lock2!(update, prog) += 5.0;
info!("Update | Init ... OK ... {}%", lock2!(update, prog));
*update.lock().unwrap().prog.lock().unwrap() += 5.0;
info!(
"Update | Init ... OK ... {}%",
update.lock().unwrap().prog.lock().unwrap()
);
//---------------------------------------------------------------------------------------------------- Metadata
*lock2!(update, msg) = MSG_METADATA.to_string();
*update.lock().unwrap().msg.lock().unwrap() = MSG_METADATA.to_string();
info!("Update | {}", METADATA);
// Loop process:
// reqwest will retry himself
@ -457,11 +461,11 @@ impl Update {
return Err(anyhow!("Metadata fetch failed"));
};
*lock2!(update, prog) += 10.0;
*update.lock().unwrap().prog.lock().unwrap() += 10.0;
info!("Update | Gupaxx {} ... OK", new_ver);
//---------------------------------------------------------------------------------------------------- Compare
*lock2!(update, msg) = MSG_COMPARE.to_string();
*update.lock().unwrap().msg.lock().unwrap() = MSG_COMPARE.to_string();
info!("Update | {}", COMPARE);
let diff = GUPAX_VERSION != new_ver;
if diff {
@ -475,18 +479,21 @@ impl Update {
GUPAX_VERSION, new_ver
);
info!("Update | All packages up-to-date ... RETURNING");
*lock2!(update, prog) = 100.0;
*lock2!(update, msg) = MSG_UP_TO_DATE.to_string();
*update.lock().unwrap().prog.lock().unwrap() = 100.0;
*update.lock().unwrap().msg.lock().unwrap() = MSG_UP_TO_DATE.to_string();
return Ok(());
}
*lock2!(update, prog) += 5.0;
info!("Update | Compare ... OK ... {}%", lock2!(update, prog));
*update.lock().unwrap().prog.lock().unwrap() += 5.0;
info!(
"Update | Compare ... OK ... {}%",
update.lock().unwrap().prog.lock().unwrap()
);
// Return if 0 (all packages up-to-date)
// Get amount of packages to divide up the percentage increases
//---------------------------------------------------------------------------------------------------- Download
*lock2!(update, msg) = format!("{} Gupaxx", MSG_DOWNLOAD);
*update.lock().unwrap().msg.lock().unwrap() = format!("{} Gupaxx", MSG_DOWNLOAD);
info!("Update | {}", DOWNLOAD);
// Clone data before async
let version = new_ver;
@ -500,7 +507,7 @@ impl Update {
// arch
// standalone or bundled
// archive extension
let bundle = if lock!(og).gupax.bundled {
let bundle = if og.lock().unwrap().gupax.bundled {
"bundle"
} else {
"standalone"
@ -527,12 +534,15 @@ impl Update {
error!("Update | Download ... FAIL");
return Err(anyhow!("Download failed"));
};
*lock2!(update, prog) += 30.0;
*update.lock().unwrap().prog.lock().unwrap() += 30.0;
info!("Update | Gupaxx ... OK");
info!("Update | Download ... OK ... {}%", *lock2!(update, prog));
info!(
"Update | Download ... OK ... {}%",
*update.lock().unwrap().prog.lock().unwrap()
);
//---------------------------------------------------------------------------------------------------- Extract
*lock2!(update, msg) = format!("{} Gupaxx", MSG_EXTRACT);
*update.lock().unwrap().msg.lock().unwrap() = format!("{} Gupaxx", MSG_EXTRACT);
info!("Update | {}", EXTRACT);
let tmp = tmp_dir.to_owned();
#[cfg(target_os = "windows")]
@ -542,9 +552,12 @@ impl Update {
)?;
#[cfg(target_family = "unix")]
tar::Archive::new(flate2::read::GzDecoder::new(bytes.as_ref())).unpack(tmp)?;
*lock2!(update, prog) += 5.0;
*update.lock().unwrap().prog.lock().unwrap() += 5.0;
info!("Update | Gupaxx ... OK");
info!("Update | Extract ... OK ... {}%", *lock2!(update, prog));
info!(
"Update | Extract ... OK ... {}%",
*update.lock().unwrap().prog.lock().unwrap()
);
//---------------------------------------------------------------------------------------------------- Upgrade
// if bundled, directories p2pool, xmrig and xmrig-proxy will exist.
@ -553,7 +566,7 @@ impl Update {
//
// 3. Rename tmp path into current path
// 4. Update [State/Version]
*lock2!(update, msg) = format!("Gupaxx {}", MSG_UPGRADE);
*update.lock().unwrap().msg.lock().unwrap() = format!("Gupaxx {}", MSG_UPGRADE);
info!("Update | {}", UPGRADE);
// If this bool doesn't get set, something has gone wrong because
// we _didn't_ find a binary even though we downloaded it.
@ -569,11 +582,11 @@ impl Update {
.to_str()
.ok_or_else(|| anyhow!("WalkDir basename failed"))?;
let path = match name {
GUPAX_BINARY => lock!(update).path_gupax.clone(),
P2POOL_BINARY => lock!(update).path_p2pool.clone(),
XMRIG_BINARY => lock!(update).path_xmrig.clone(),
XMRIG_PROXY_BINARY => lock!(update).path_xp.clone(),
NODE_BINARY => lock!(update).path_node.clone(),
GUPAX_BINARY => update.lock().unwrap().path_gupax.clone(),
P2POOL_BINARY => update.lock().unwrap().path_p2pool.clone(),
XMRIG_BINARY => update.lock().unwrap().path_xmrig.clone(),
XMRIG_PROXY_BINARY => update.lock().unwrap().path_xp.clone(),
NODE_BINARY => update.lock().unwrap().path_node.clone(),
_ => continue,
};
found = true;
@ -606,7 +619,7 @@ impl Update {
path.display()
);
// if bundled, create directory for p2pool, xmrig and xmrig-proxy if not present
if lock!(og).gupax.bundled
if og.lock().unwrap().gupax.bundled
&& (name == P2POOL_BINARY
|| name == XMRIG_BINARY
|| name == XMRIG_PROXY_BINARY
@ -620,8 +633,8 @@ impl Update {
// Move downloaded path into old path
std::fs::rename(entry.path(), path)?;
// If we're updating Gupax, set the [Restart] state so that the user knows to restart
*lock!(restart) = Restart::Yes;
*lock2!(update, prog) += 5.0;
*restart.lock().unwrap() = Restart::Yes;
*update.lock().unwrap().prog.lock().unwrap() += 5.0;
}
if !found {
return Err(anyhow!("Fatal error: Package binary could not be found"));
@ -635,11 +648,11 @@ impl Update {
let seconds = now.elapsed().as_secs();
info!("Update | Seconds elapsed ... [{}s]", seconds);
*lock2!(update, msg) = format!(
*update.lock().unwrap().msg.lock().unwrap() = format!(
"Updated from {} to {}\nYou need to restart Gupaxx.",
GUPAX_VERSION, version
);
*lock2!(update, prog) = 100.0;
*update.lock().unwrap().prog.lock().unwrap() = 100.0;
Ok(())
}
}

View file

@ -26,7 +26,7 @@
// found here, e.g: User clicks [Stop P2Pool] -> Arc<Mutex<ProcessSignal> is set
// indicating to this thread during its loop: "I should stop P2Pool!", e.g:
//
// if lock!(p2pool).signal == ProcessSignal::Stop {
// if p2pool.lock().unwrap().signal == ProcessSignal::Stop {
// stop_p2pool(),
// }
//
@ -430,7 +430,7 @@ impl Helper {
// order as the main GUI thread (top to bottom).
let helper = Arc::clone(helper);
let lock = lock!(helper);
let lock = helper.lock().unwrap();
let node = Arc::clone(&lock.node);
let p2pool = Arc::clone(&lock.p2pool);
let xmrig = Arc::clone(&lock.xmrig);
@ -465,39 +465,39 @@ impl Helper {
// down the culprit of an [Arc<Mutex>] deadlock. I know, they're ugly.
// 2. Lock... EVERYTHING!
let mut lock = lock!(helper);
let mut lock = helper.lock().unwrap();
debug!("Helper | Locking (1/15) ... [helper]");
let node = lock!(node);
let node = node.lock().unwrap();
debug!("Helper | Locking (2/15) ... [helper]");
let p2pool = lock!(p2pool);
let p2pool = p2pool.lock().unwrap();
debug!("Helper | Locking (3/15) ... [p2pool]");
let xmrig = lock!(xmrig);
let xmrig = xmrig.lock().unwrap();
debug!("Helper | Locking (4/15) ... [xmrig]");
let xmrig_proxy = lock!(xmrig_proxy);
let xmrig_proxy = xmrig_proxy.lock().unwrap();
debug!("Helper | Locking (5/15) ... [xmrig_proxy]");
let xvb = lock!(xvb);
let xvb = xvb.lock().unwrap();
debug!("Helper | Locking (6/15) ... [xvb]");
let mut lock_pub_sys = lock!(pub_sys);
let mut lock_pub_sys = pub_sys.lock().unwrap();
debug!("Helper | Locking (8/15) ... [gui_api_node]");
let mut gui_api_node = lock!(gui_api_node);
let mut gui_api_node = gui_api_node.lock().unwrap();
debug!("Helper | Locking (7/15) ... [pub_sys]");
let mut gui_api_p2pool = lock!(gui_api_p2pool);
let mut gui_api_p2pool = gui_api_p2pool.lock().unwrap();
debug!("Helper | Locking (8/15) ... [gui_api_p2pool]");
let mut gui_api_xmrig = lock!(gui_api_xmrig);
let mut gui_api_xmrig = gui_api_xmrig.lock().unwrap();
debug!("Helper | Locking (9/15) ... [gui_api_xmrig]");
let mut gui_api_xp = lock!(gui_api_xp);
let mut gui_api_xp = gui_api_xp.lock().unwrap();
debug!("Helper | Locking (10/15) ... [gui_api_xp]");
let mut gui_api_xvb = lock!(gui_api_xvb);
let mut gui_api_xvb = gui_api_xvb.lock().unwrap();
debug!("Helper | Locking (11/15) ... [gui_api_xvb]");
let mut pub_api_node = lock!(pub_api_node);
let mut pub_api_node = pub_api_node.lock().unwrap();
debug!("Helper | Locking (14/15) ... [pub_api_node]");
let mut pub_api_p2pool = lock!(pub_api_p2pool);
let mut pub_api_p2pool = pub_api_p2pool.lock().unwrap();
debug!("Helper | Locking (14/15) ... [pub_api_p2pool]");
let mut pub_api_xmrig = lock!(pub_api_xmrig);
let mut pub_api_xmrig = pub_api_xmrig.lock().unwrap();
debug!("Helper | Locking (13/15) ... [pub_api_xmrig]");
let mut pub_api_xp = lock!(pub_api_xp);
let mut pub_api_xp = pub_api_xp.lock().unwrap();
debug!("Helper | Locking (14/15) ... [pub_api_xp]");
let mut pub_api_xvb = lock!(pub_api_xvb);
let mut pub_api_xvb = pub_api_xvb.lock().unwrap();
debug!("Helper | Locking (15/15) ... [pub_api_xvb]");
// Calculate Gupax's uptime always.
lock.uptime = HumanTime::into_human(lock.instant.elapsed());
@ -619,7 +619,7 @@ fn check_died(
gui_api_output_raw: &mut String,
) -> bool {
// Check if the process secretly died without us knowing :)
if let Ok(Some(code)) = lock!(child_pty).try_wait() {
if let Ok(Some(code)) = child_pty.lock().unwrap().try_wait() {
debug!(
"{} Watchdog | Process secretly died on us! Getting exit status...",
process.name
@ -659,7 +659,7 @@ fn check_died(
false
}
fn check_user_input(process: &Arc<Mutex<Process>>, stdin: &mut Box<dyn std::io::Write + Send>) {
let mut lock = lock!(process);
let mut lock = process.lock().unwrap();
if !lock.input.is_empty() {
let input = std::mem::take(&mut lock.input);
for line in input {
@ -691,32 +691,32 @@ fn signal_end(
start: &Instant,
gui_api_output_raw: &mut String,
) -> bool {
if lock!(process).signal == ProcessSignal::Stop {
debug!("{} Watchdog | Stop SIGNAL caught", lock!(process).name);
if process.lock().unwrap().signal == ProcessSignal::Stop {
debug!("{} Watchdog | Stop SIGNAL caught", process.lock().unwrap().name);
// This actually sends a SIGHUP to p2pool (closes the PTY, hangs up on p2pool)
if let Err(e) = lock!(child_pty).kill() {
error!("{} Watchdog | Kill error: {}", lock!(process).name, e);
if let Err(e) = child_pty.lock().unwrap().kill() {
error!("{} Watchdog | Kill error: {}", process.lock().unwrap().name, e);
}
// Wait to get the exit status
let exit_status = match lock!(child_pty).wait() {
let exit_status = match child_pty.lock().unwrap().wait() {
Ok(e) => {
if e.success() {
lock!(process).state = ProcessState::Dead;
process.lock().unwrap().state = ProcessState::Dead;
"Successful"
} else {
lock!(process).state = ProcessState::Failed;
process.lock().unwrap().state = ProcessState::Failed;
"Failed"
}
}
_ => {
lock!(process).state = ProcessState::Failed;
process.lock().unwrap().state = ProcessState::Failed;
"Unknown Error"
}
};
let uptime = HumanTime::into_human(start.elapsed());
info!(
"{} Watchdog | Stopped ... Uptime was: [{}], Exit status: [{}]",
lock!(process).name,
process.lock().unwrap().name,
uptime,
exit_status
);
@ -724,7 +724,7 @@ fn signal_end(
if let Err(e) = writeln!(
gui_api_output_raw,
"{}\n{} stopped | Uptime: [{}] | Exit status: [{}]\n{}\n\n\n\n",
lock!(process).name,
process.lock().unwrap().name,
HORI_CONSOLE,
uptime,
exit_status,
@ -732,25 +732,25 @@ fn signal_end(
) {
error!(
"{} Watchdog | GUI Uptime/Exit status write failed: {}",
lock!(process).name,
process.lock().unwrap().name,
e
);
}
lock!(process).signal = ProcessSignal::None;
process.lock().unwrap().signal = ProcessSignal::None;
debug!(
"{} Watchdog | Stop SIGNAL done, breaking",
lock!(process).name,
process.lock().unwrap().name,
);
return true;
// Check RESTART
} else if lock!(process).signal == ProcessSignal::Restart {
debug!("{} Watchdog | Restart SIGNAL caught", lock!(process).name,);
} else if process.lock().unwrap().signal == ProcessSignal::Restart {
debug!("{} Watchdog | Restart SIGNAL caught", process.lock().unwrap().name,);
// This actually sends a SIGHUP to p2pool (closes the PTY, hangs up on p2pool)
if let Err(e) = lock!(child_pty).kill() {
error!("{} Watchdog | Kill error: {}", lock!(process).name, e);
if let Err(e) = child_pty.lock().unwrap().kill() {
error!("{} Watchdog | Kill error: {}", process.lock().unwrap().name, e);
}
// Wait to get the exit status
let exit_status = match lock!(child_pty).wait() {
let exit_status = match child_pty.lock().unwrap().wait() {
Ok(e) => {
if e.success() {
"Successful"
@ -763,7 +763,7 @@ fn signal_end(
let uptime = HumanTime::into_human(start.elapsed());
info!(
"{} Watchdog | Stopped ... Uptime was: [{}], Exit status: [{}]",
lock!(process).name,
process.lock().unwrap().name,
uptime,
exit_status
);
@ -771,7 +771,7 @@ fn signal_end(
if let Err(e) = writeln!(
gui_api_output_raw,
"{}\n{} stopped | Uptime: [{}] | Exit status: [{}]\n{}\n\n\n\n",
lock!(process).name,
process.lock().unwrap().name,
HORI_CONSOLE,
uptime,
exit_status,
@ -779,14 +779,14 @@ fn signal_end(
) {
error!(
"{} Watchdog | GUI Uptime/Exit status write failed: {}",
lock!(process).name,
process.lock().unwrap().name,
e
);
}
lock!(process).state = ProcessState::Waiting;
process.lock().unwrap().state = ProcessState::Waiting;
debug!(
"{} Watchdog | Restart SIGNAL done, breaking",
lock!(process).name,
process.lock().unwrap().name,
);
return true;
}

View file

@ -18,11 +18,11 @@ use crate::{
check_died, check_user_input, signal_end, sleep_end_loop, ProcessName, ProcessSignal,
ProcessState,
},
macros::{arc_mut, lock2, sleep},
macros::{arc_mut, sleep},
};
use std::fmt::Write;
use super::{lock, Helper, HumanNumber, HumanTime, Process};
use super::{Helper, HumanNumber, HumanTime, Process};
impl Helper {
#[cold]
@ -38,18 +38,18 @@ impl Helper {
// Run a ANSI escape sequence filter.
while let Some(Ok(line)) = stdout.next() {
let line = strip_ansi_escapes::strip_str(line);
if let Err(e) = writeln!(lock!(output_parse), "{}", line) {
if let Err(e) = writeln!(output_parse.lock().unwrap(), "{}", line) {
error!("Node PTY Parse | Output error: {}", e);
}
if let Err(e) = writeln!(lock!(output_pub), "{}", line) {
if let Err(e) = writeln!(output_pub.lock().unwrap(), "{}", line) {
error!("Node PTY Pub | Output error: {}", e);
}
}
while let Some(Ok(line)) = stdout.next() {
if let Err(e) = writeln!(lock!(output_parse), "{}", line) {
if let Err(e) = writeln!(output_parse.lock().unwrap(), "{}", line) {
error!("P2Pool PTY Parse | Output error: {}", e);
}
if let Err(e) = writeln!(lock!(output_pub), "{}", line) {
if let Err(e) = writeln!(output_pub.lock().unwrap(), "{}", line) {
error!("P2Pool PTY Pub | Output error: {}", e);
}
}
@ -121,12 +121,12 @@ impl Helper {
// Just sets some signals for the watchdog thread to pick up on.
pub fn stop_node(helper: &Arc<Mutex<Self>>) {
info!("Node | Attempting to stop...");
lock2!(helper, node).signal = ProcessSignal::Stop;
lock2!(helper, node).state = ProcessState::Middle;
let gui_api = Arc::clone(&lock!(helper).gui_api_node);
let pub_api = Arc::clone(&lock!(helper).pub_api_node);
*lock!(pub_api) = PubNodeApi::new();
*lock!(gui_api) = PubNodeApi::new();
helper.lock().unwrap().node.lock().unwrap().signal = ProcessSignal::Stop;
helper.lock().unwrap().node.lock().unwrap().state = ProcessState::Middle;
let gui_api = Arc::clone(&helper.lock().unwrap().gui_api_node);
let pub_api = Arc::clone(&helper.lock().unwrap().pub_api_node);
*pub_api.lock().unwrap() = PubNodeApi::new();
*gui_api.lock().unwrap() = PubNodeApi::new();
}
#[cold]
#[inline(never)]
@ -134,15 +134,15 @@ impl Helper {
// Basically calls to kill the current p2pool, waits a little, then starts the below function in a a new thread, then exit.
pub fn restart_node(helper: &Arc<Mutex<Self>>, state: &Node, path: &Path) {
info!("Node | Attempting to restart...");
lock2!(helper, node).signal = ProcessSignal::Restart;
lock2!(helper, node).state = ProcessState::Middle;
helper.lock().unwrap().node.lock().unwrap().signal = ProcessSignal::Restart;
helper.lock().unwrap().node.lock().unwrap().state = ProcessState::Middle;
let helper = Arc::clone(helper);
let state = state.clone();
let path = path.to_path_buf();
// This thread lives to wait, start p2pool then die.
thread::spawn(move || {
while lock2!(helper, node).state != ProcessState::Waiting {
while helper.lock().unwrap().node.lock().unwrap().state != ProcessState::Waiting {
warn!("Node | Want to restart but process is still alive, waiting...");
sleep!(1000);
}
@ -156,7 +156,7 @@ impl Helper {
#[inline(never)]
// The "frontend" function that parses the arguments, and spawns either the [Simple] or [Advanced] Node watchdog thread.
pub fn start_node(helper: &Arc<Mutex<Self>>, state: &Node, path: &Path) {
lock2!(helper, node).state = ProcessState::Middle;
helper.lock().unwrap().node.lock().unwrap().state = ProcessState::Middle;
let args = Self::build_node_args(state);
@ -164,9 +164,9 @@ impl Helper {
crate::disk::print_dash(&format!("Node | Launch arguments: {:#?}", args));
// Spawn watchdog thread
let process = Arc::clone(&lock!(helper).node);
let gui_api = Arc::clone(&lock!(helper).gui_api_node);
let pub_api = Arc::clone(&lock!(helper).pub_api_node);
let process = Arc::clone(&helper.lock().unwrap().node);
let gui_api = Arc::clone(&helper.lock().unwrap().gui_api_node);
let pub_api = Arc::clone(&helper.lock().unwrap().pub_api_node);
let path = path.to_path_buf();
let state = state.clone();
thread::spawn(move || {
@ -184,7 +184,7 @@ impl Helper {
path: std::path::PathBuf,
state: Node,
) {
lock!(process).start = Instant::now();
process.lock().unwrap().start = Instant::now();
// spawn pty
debug!("Node | Creating PTY...");
let pty = portable_pty::native_pty_system();
@ -199,8 +199,8 @@ impl Helper {
// 4. Spawn PTY read thread
debug!("Node | Spawning PTY read thread...");
let reader = pair.master.try_clone_reader().unwrap(); // Get STDOUT/STDERR before moving the PTY
let output_parse = Arc::clone(&lock!(process).output_parse);
let output_pub = Arc::clone(&lock!(process).output_pub);
let output_parse = Arc::clone(&process.lock().unwrap().output_parse);
let output_pub = Arc::clone(&process.lock().unwrap().output_pub);
spawn(enc!((output_parse, output_pub) async move {
Self::read_pty_node(output_parse, output_pub, reader);
}));
@ -216,13 +216,13 @@ impl Helper {
let mut stdin = pair.master.take_writer().unwrap();
// set state
let client = Client::new();
lock!(process).state = ProcessState::Syncing;
lock!(process).signal = ProcessSignal::None;
process.lock().unwrap().state = ProcessState::Syncing;
process.lock().unwrap().signal = ProcessSignal::None;
// reset stats
*lock!(pub_api) = PubNodeApi::new();
*lock!(gui_api) = PubNodeApi::new();
*pub_api.lock().unwrap() = PubNodeApi::new();
*gui_api.lock().unwrap() = PubNodeApi::new();
// loop
let start = lock!(process).start;
let start = process.lock().unwrap().start;
info!("Node | Entering watchdog mode... woof!");
loop {
let now = Instant::now();
@ -231,14 +231,19 @@ impl Helper {
// check state
if check_died(
&child_pty,
&mut lock!(process),
&mut process.lock().unwrap(),
&start,
&mut lock!(gui_api).output,
&mut gui_api.lock().unwrap().output,
) {
break;
}
// check signal
if signal_end(process, &child_pty, &start, &mut lock!(gui_api).output) {
if signal_end(
process,
&child_pty,
&start,
&mut gui_api.lock().unwrap().output,
) {
break;
}
// check user input
@ -248,7 +253,7 @@ impl Helper {
// Check if logs need resetting
debug!("Node Watchdog | Attempting GUI log reset check");
{
let mut lock = lock!(gui_api);
let mut lock = gui_api.lock().unwrap();
Self::check_reset_gui_output(&mut lock.output, ProcessName::Node);
}
// No need to check output since monerod has a sufficient API
@ -261,7 +266,7 @@ impl Helper {
Ok(priv_api) => {
debug!("Node Watchdog | HTTP API request OK, attempting [update_from_priv()]");
if priv_api.result.synchronized && priv_api.result.status == "OK" {
lock!(process).state = ProcessState::Alive
process.lock().unwrap().state = ProcessState::Alive
}
PubNodeApi::update_from_priv(pub_api, priv_api);
}
@ -332,7 +337,7 @@ impl PubNodeApi {
}
}
fn update_from_priv(public: &Arc<Mutex<Self>>, private: PrivNodeApi) {
let mut public = lock!(public);
let mut public = public.lock().unwrap();
*public = Self {
blockheight: HumanNumber::from_u64(private.result.height),
difficulty: HumanNumber::from_u64(private.result.difficulty),
@ -352,10 +357,10 @@ impl PubNodeApi {
elapsed: std::time::Duration,
) {
// 1. Take the process's current output buffer and combine it with Pub (if not empty)
let mut output_pub = lock!(output_pub);
let mut output_pub = output_pub.lock().unwrap();
{
let mut public = lock!(public);
let mut public = public.lock().unwrap();
if !output_pub.is_empty() {
public.output.push_str(&std::mem::take(&mut *output_pub));
}

View file

@ -53,10 +53,10 @@ impl Helper {
while let Some(Ok(line)) = stdout.next() {
let line = strip_ansi_escapes::strip_str(line);
if let Err(e) = writeln!(lock!(output_parse), "{}", line) {
if let Err(e) = writeln!(output_parse.lock().unwrap(), "{}", line) {
error!("P2Pool PTY Parse | Output error: {}", e);
}
if let Err(e) = writeln!(lock!(output_pub), "{}", line) {
if let Err(e) = writeln!(output_pub.lock().unwrap(), "{}", line) {
error!("P2Pool PTY Pub | Output error: {}", e);
}
if i > 20 {
@ -81,10 +81,10 @@ impl Helper {
ehr
);
// multiply by a thousand because value is given as kH/s instead H/s
lock!(gui_api).sidechain_ehr = ehr;
gui_api.lock().unwrap().sidechain_ehr = ehr;
debug!(
"P2pool | PTY getting current estimated HR data from status: {} H/s",
lock!(gui_api).sidechain_ehr
gui_api.lock().unwrap().sidechain_ehr
);
} else {
error!("P2pool | PTY Getting data from status: Lines contains Your shares but no value found: {}", line);
@ -97,7 +97,7 @@ impl Helper {
"P2pool | PTY getting current shares data from status: {} share",
shares
);
lock!(gui_api).sidechain_shares = shares;
gui_api.lock().unwrap().sidechain_shares = shares;
} else {
error!("P2pool | PTY Getting data from status: Lines contains Your shares but no value found: {}", line);
}
@ -114,23 +114,23 @@ impl Helper {
let (date, atomic_unit, block) = PayoutOrd::parse_raw_payout_line(&line);
let formatted_log_line = GupaxP2poolApi::format_payout(&date, &atomic_unit, &block);
GupaxP2poolApi::add_payout(
&mut lock!(gupax_p2pool_api),
&mut gupax_p2pool_api.lock().unwrap(),
&formatted_log_line,
date,
atomic_unit,
block,
);
if let Err(e) = GupaxP2poolApi::write_to_all_files(
&lock!(gupax_p2pool_api),
&gupax_p2pool_api.lock().unwrap(),
&formatted_log_line,
) {
error!("P2Pool PTY GupaxP2poolApi | Write error: {}", e);
}
}
if let Err(e) = writeln!(lock!(output_parse), "{}", line) {
if let Err(e) = writeln!(output_parse.lock().unwrap(), "{}", line) {
error!("P2Pool PTY Parse | Output error: {}", e);
}
if let Err(e) = writeln!(lock!(output_pub), "{}", line) {
if let Err(e) = writeln!(output_pub.lock().unwrap(), "{}", line) {
error!("P2Pool PTY Pub | Output error: {}", e);
}
}
@ -141,8 +141,8 @@ impl Helper {
// Just sets some signals for the watchdog thread to pick up on.
pub fn stop_p2pool(helper: &Arc<Mutex<Self>>) {
info!("P2Pool | Attempting to stop...");
lock2!(helper, p2pool).signal = ProcessSignal::Stop;
lock2!(helper, p2pool).state = ProcessState::Middle;
helper.lock().unwrap().p2pool.lock().unwrap().signal = ProcessSignal::Stop;
helper.lock().unwrap().p2pool.lock().unwrap().state = ProcessState::Middle;
}
#[cold]
@ -156,15 +156,15 @@ impl Helper {
backup_hosts: Option<Vec<Node>>,
) {
info!("P2Pool | Attempting to restart...");
lock2!(helper, p2pool).signal = ProcessSignal::Restart;
lock2!(helper, p2pool).state = ProcessState::Middle;
helper.lock().unwrap().p2pool.lock().unwrap().signal = ProcessSignal::Restart;
helper.lock().unwrap().p2pool.lock().unwrap().state = ProcessState::Middle;
let helper = Arc::clone(helper);
let state = state.clone();
let path = path.to_path_buf();
// This thread lives to wait, start p2pool then die.
thread::spawn(move || {
while lock2!(helper, p2pool).state != ProcessState::Waiting {
while helper.lock().unwrap().p2pool.lock().unwrap().state != ProcessState::Waiting {
warn!("P2Pool | Want to restart but process is still alive, waiting...");
sleep!(1000);
}
@ -184,7 +184,7 @@ impl Helper {
path: &Path,
backup_hosts: Option<Vec<Node>>,
) {
lock2!(helper, p2pool).state = ProcessState::Middle;
helper.lock().unwrap().p2pool.lock().unwrap().state = ProcessState::Middle;
let (args, api_path_local, api_path_network, api_path_pool) =
Self::build_p2pool_args_and_mutate_img(helper, state, path, backup_hosts);
@ -199,10 +199,10 @@ impl Helper {
));
// Spawn watchdog thread
let process = Arc::clone(&lock!(helper).p2pool);
let gui_api = Arc::clone(&lock!(helper).gui_api_p2pool);
let pub_api = Arc::clone(&lock!(helper).pub_api_p2pool);
let gupax_p2pool_api = Arc::clone(&lock!(helper).gupax_p2pool_api);
let process = Arc::clone(&helper.lock().unwrap().p2pool);
let gui_api = Arc::clone(&helper.lock().unwrap().gui_api_p2pool);
let pub_api = Arc::clone(&helper.lock().unwrap().pub_api_p2pool);
let gupax_p2pool_api = Arc::clone(&helper.lock().unwrap().gupax_p2pool_api);
let path = path.to_path_buf();
thread::spawn(move || {
Self::spawn_p2pool_watchdog(
@ -278,7 +278,7 @@ impl Helper {
}
}
*lock2!(helper, img_p2pool) = ImgP2pool {
*helper.lock().unwrap().img_p2pool.lock().unwrap() = ImgP2pool {
mini: "P2Pool Mini".to_string(),
address: Self::head_tail_of_monero_address(&state.address),
host: ip.to_string(),
@ -305,7 +305,7 @@ impl Helper {
args.push("--mini".to_string()); // P2Pool Mini
args.push("--light-mode".to_string()); // Assume user is not using P2Pool to mine.
*lock2!(helper, img_p2pool) = ImgP2pool {
*helper.lock().unwrap().img_p2pool.lock().unwrap() = ImgP2pool {
mini: "P2Pool Mini".to_string(),
address: Self::head_tail_of_monero_address(&state.address),
host: "Local node".to_string(),
@ -322,8 +322,8 @@ impl Helper {
// This parses the input and attempts to fill out
// the [ImgP2pool]... This is pretty bad code...
let mut last = "";
let lock = lock!(helper);
let mut p2pool_image = lock!(lock.img_p2pool);
let lock = helper.lock().unwrap();
let mut p2pool_image = lock.img_p2pool.lock().unwrap();
let mut mini = false;
for arg in state.arguments.split_whitespace() {
match last {
@ -398,7 +398,7 @@ impl Helper {
}
}
*lock2!(helper, img_p2pool) = ImgP2pool {
*helper.lock().unwrap().img_p2pool.lock().unwrap() = ImgP2pool {
mini: if state.mini {
"P2Pool Mini".to_string()
} else {
@ -464,7 +464,7 @@ impl Helper {
// 2. Set process state
debug!("P2Pool | Setting process state...");
let mut lock = lock!(process);
let mut lock = process.lock().unwrap();
lock.state = ProcessState::Syncing;
lock.signal = ProcessSignal::None;
lock.start = Instant::now();
@ -474,8 +474,8 @@ impl Helper {
// 3. Spawn PTY read thread
debug!("P2Pool | Spawning PTY read thread...");
let output_parse = Arc::clone(&lock!(process).output_parse);
let output_pub = Arc::clone(&lock!(process).output_pub);
let output_parse = Arc::clone(&process.lock().unwrap().output_parse);
let output_pub = Arc::clone(&process.lock().unwrap().output_pub);
let gupax_p2pool_api = Arc::clone(&gupax_p2pool_api);
let p2pool_api_c = Arc::clone(&gui_api);
tokio::spawn(async move {
@ -487,8 +487,8 @@ impl Helper {
p2pool_api_c,
);
});
let output_parse = Arc::clone(&lock!(process).output_parse);
let output_pub = Arc::clone(&lock!(process).output_pub);
let output_parse = Arc::clone(&process.lock().unwrap().output_parse);
let output_pub = Arc::clone(&process.lock().unwrap().output_pub);
debug!("P2Pool | Cleaning old [local] API files...");
// Attempt to remove stale API file
@ -511,11 +511,11 @@ impl Helper {
),
}
}
let start = lock!(process).start;
let start = process.lock().unwrap().start;
// Reset stats before loop
*lock!(pub_api) = PubP2poolApi::new();
*lock!(gui_api) = PubP2poolApi::new();
*pub_api.lock().unwrap() = PubP2poolApi::new();
*gui_api.lock().unwrap() = PubP2poolApi::new();
// 4. Loop as watchdog
let mut first_loop = true;
@ -527,27 +527,32 @@ impl Helper {
// Set timer
let now = Instant::now();
debug!("P2Pool Watchdog | ----------- Start of loop -----------");
lock!(gui_api).tick = (last_p2pool_request.elapsed().as_secs() % 60) as u8;
gui_api.lock().unwrap().tick = (last_p2pool_request.elapsed().as_secs() % 60) as u8;
// Check if the process is secretly died without us knowing :)
if check_died(
&child_pty,
&mut lock!(process),
&mut process.lock().unwrap(),
&start,
&mut lock!(gui_api).output,
&mut gui_api.lock().unwrap().output,
) {
break;
}
// Check SIGNAL
if signal_end(&process, &child_pty, &start, &mut lock!(gui_api).output) {
if signal_end(
&process,
&child_pty,
&start,
&mut gui_api.lock().unwrap().output,
) {
break;
}
// Check vector of user input
check_user_input(&process, &mut stdin);
// Check if logs need resetting
debug!("P2Pool Watchdog | Attempting GUI log reset check");
let mut lock = lock!(gui_api);
let mut lock = gui_api.lock().unwrap();
Self::check_reset_gui_output(&mut lock.output, ProcessName::P2pool);
drop(lock);
@ -575,8 +580,9 @@ impl Helper {
last_p2pool_request.elapsed() >= Duration::from_secs(60);
// need to reload fast to get the first right values after syncing.
// check if value is 100k or under and request immediately if that's the case. fixed in release of p2pool including commit https://github.com/SChernykh/p2pool/commit/64a199be6dec7924b41f857a401086f25e1ec9be
if (last_p2pool_request_expired || lock!(pub_api).p2pool_difficulty_u64 <= 100000)
&& lock!(process).state == ProcessState::Alive
if (last_p2pool_request_expired
|| pub_api.lock().unwrap().p2pool_difficulty_u64 <= 100000)
&& process.lock().unwrap().state == ProcessState::Alive
{
debug!("P2Pool Watchdog | Attempting [network] & [pool] API file read");
if let (Ok(network_api), Ok(pool_api)) = (
@ -597,7 +603,7 @@ impl Helper {
last_status_request.elapsed() >= Duration::from_secs(60);
if (last_status_request_expired || first_loop)
&& lock!(process).state == ProcessState::Alive
&& process.lock().unwrap().state == ProcessState::Alive
{
debug!("P2Pool Watchdog | Reading status output of p2pool node");
#[cfg(target_os = "windows")]
@ -622,7 +628,7 @@ impl Helper {
sleep_end_loop(now, ProcessName::P2pool).await;
debug!(
"P2Pool Watchdog | END OF LOOP - Tick: [{}/60]",
lock!(gui_api).tick,
gui_api.lock().unwrap().tick,
);
}
@ -827,37 +833,39 @@ impl PubP2poolApi {
process: &Arc<Mutex<Process>>,
) {
// 1. Take the process's current output buffer and combine it with Pub (if not empty)
let mut output_pub = lock!(output_pub);
let mut output_pub = output_pub.lock().unwrap();
if !output_pub.is_empty() {
lock!(public)
public
.lock()
.unwrap()
.output
.push_str(&std::mem::take(&mut *output_pub));
}
// 2. Parse the full STDOUT
let mut output_parse = lock!(output_parse);
let mut output_parse = output_parse.lock().unwrap();
let (payouts_new, xmr_new) = Self::calc_payouts_and_xmr(&output_parse);
// Check for "SYNCHRONIZED" only if we aren't already.
if lock!(process).state == ProcessState::Syncing {
if process.lock().unwrap().state == ProcessState::Syncing {
// look for depth 0
if P2POOL_REGEX.depth_0.is_match(&output_parse) {
lock!(process).state = ProcessState::Alive;
process.lock().unwrap().state = ProcessState::Alive;
}
}
// check if zmq server still alive
if lock!(process).state == ProcessState::Alive
if process.lock().unwrap().state == ProcessState::Alive
&& contains_zmq_connection_lost(&output_parse)
{
// node zmq is not responding, p2pool is not ready
lock!(process).state = ProcessState::Syncing;
process.lock().unwrap().state = ProcessState::Syncing;
}
// 3. Throw away [output_parse]
output_parse.clear();
drop(output_parse);
// 4. Add to current values
let mut public = lock!(public);
let mut public = public.lock().unwrap();
let (payouts, xmr) = (public.payouts + payouts_new, public.xmr + xmr_new);
// 5. Calculate hour/day/month given elapsed time
@ -910,7 +918,7 @@ impl PubP2poolApi {
// Mutate [PubP2poolApi] with data from a [PrivP2poolLocalApi] and the process output.
pub(super) fn update_from_local(public: &Arc<Mutex<Self>>, local: PrivP2poolLocalApi) {
let mut public = lock!(public);
let mut public = public.lock().unwrap();
*public = Self {
hashrate_15m: HumanNumber::from_u64(local.hashrate_15m),
hashrate_1h: HumanNumber::from_u64(local.hashrate_1h),
@ -930,7 +938,7 @@ impl PubP2poolApi {
net: PrivP2poolNetworkApi,
pool: PrivP2poolPoolApi,
) {
let user_hashrate = lock!(public).user_p2pool_hashrate_u64; // The user's total P2Pool hashrate
let user_hashrate = public.lock().unwrap().user_p2pool_hashrate_u64; // The user's total P2Pool hashrate
let monero_difficulty = net.difficulty;
let monero_hashrate = monero_difficulty / MONERO_BLOCK_TIME_IN_SECONDS;
let p2pool_hashrate = pool.pool_statistics.hashRate;
@ -972,7 +980,7 @@ impl PubP2poolApi {
p2pool_difficulty / user_hashrate,
));
}
let mut public = lock!(public);
let mut public = public.lock().unwrap();
*public = Self {
p2pool_difficulty_u64: p2pool_difficulty,
monero_difficulty_u64: monero_difficulty,

View file

@ -425,7 +425,6 @@ Uptime = 0h 2m 4s
use crate::{
disk::state::P2pool,
helper::{p2pool::PubP2poolApi, xrig::xmrig::PubXmrigApi},
macros::lock,
};
use crate::helper::xvb::{public_stats::XvbPubStats, PubXvbApi};
@ -458,9 +457,9 @@ Uptime = 0h 2m 4s
let share = 1;
let p2pool_buffer = 5;
lock!(gui_api_xmrig).hashrate_raw_15m = 10000.0;
lock!(gui_api_xvb).stats_priv.runtime_mode = RuntimeMode::ManualXvb;
lock!(gui_api_xvb).stats_priv.runtime_manual_amount = 1000.0;
gui_api_xmrig.lock().unwrap().hashrate_raw_15m = 10000.0;
gui_api_xvb.lock().unwrap().stats_priv.runtime_mode = RuntimeMode::ManualXvb;
gui_api_xvb.lock().unwrap().stats_priv.runtime_manual_amount = 1000.0;
let algo = Algorithm::new(
&client,
@ -497,9 +496,9 @@ Uptime = 0h 2m 4s
let share = 1;
let p2pool_buffer = 5;
lock!(gui_api_xmrig).hashrate_raw_15m = 10000.0;
lock!(gui_api_xvb).stats_priv.runtime_mode = RuntimeMode::ManualP2pool;
lock!(gui_api_xvb).stats_priv.runtime_manual_amount = 1000.0;
gui_api_xmrig.lock().unwrap().hashrate_raw_15m = 10000.0;
gui_api_xvb.lock().unwrap().stats_priv.runtime_mode = RuntimeMode::ManualP2pool;
gui_api_xvb.lock().unwrap().stats_priv.runtime_manual_amount = 1000.0;
let algo = Algorithm::new(
&client,
@ -536,10 +535,14 @@ Uptime = 0h 2m 4s
let share = 1;
let p2pool_buffer = 5;
lock!(gui_api_xmrig).hashrate_raw_15m = 10000.0;
lock!(gui_api_xvb).stats_priv.runtime_mode = RuntimeMode::ManualDonationLevel;
lock!(gui_api_xvb).stats_priv.runtime_manual_amount = 1000.0;
lock!(gui_api_xvb).stats_priv.runtime_manual_donation_level = RuntimeDonationLevel::Donor;
gui_api_xmrig.lock().unwrap().hashrate_raw_15m = 10000.0;
gui_api_xvb.lock().unwrap().stats_priv.runtime_mode = RuntimeMode::ManualDonationLevel;
gui_api_xvb.lock().unwrap().stats_priv.runtime_manual_amount = 1000.0;
gui_api_xvb
.lock()
.unwrap()
.stats_priv
.runtime_manual_donation_level = RuntimeDonationLevel::Donor;
let algo = Algorithm::new(
&client,
@ -576,9 +579,9 @@ Uptime = 0h 2m 4s
let share = 1;
let p2pool_buffer = 5;
lock!(gui_api_p2pool).p2pool_difficulty_u64 = 9_000_000;
lock!(gui_api_xmrig).hashrate_raw_15m = 20000.0;
lock!(gui_api_xvb).stats_priv.runtime_mode = RuntimeMode::Auto;
gui_api_p2pool.lock().unwrap().p2pool_difficulty_u64 = 9_000_000;
gui_api_xmrig.lock().unwrap().hashrate_raw_15m = 20000.0;
gui_api_xvb.lock().unwrap().stats_priv.runtime_mode = RuntimeMode::Auto;
let algo = Algorithm::new(
&client,
@ -598,9 +601,9 @@ Uptime = 0h 2m 4s
assert_eq!(algo.stats.target_donation_hashrate, 10000.0);
lock!(gui_api_p2pool).p2pool_difficulty_u64 = 95_000_000;
lock!(gui_api_xmrig).hashrate_raw_15m = 10000.0;
lock!(gui_api_xvb).stats_priv.runtime_mode = RuntimeMode::Auto;
gui_api_p2pool.lock().unwrap().p2pool_difficulty_u64 = 95_000_000;
gui_api_xmrig.lock().unwrap().hashrate_raw_15m = 10000.0;
gui_api_xvb.lock().unwrap().stats_priv.runtime_mode = RuntimeMode::Auto;
let algo = Algorithm::new(
&client,
@ -637,9 +640,9 @@ Uptime = 0h 2m 4s
let share = 1;
let p2pool_buffer = 5;
lock!(gui_api_p2pool).p2pool_difficulty_u64 = 95_000_000;
lock!(gui_api_xmrig).hashrate_raw_15m = 20000.0;
lock!(gui_api_xvb).stats_priv.runtime_mode = RuntimeMode::Hero;
gui_api_p2pool.lock().unwrap().p2pool_difficulty_u64 = 95_000_000;
gui_api_xmrig.lock().unwrap().hashrate_raw_15m = 20000.0;
gui_api_xvb.lock().unwrap().stats_priv.runtime_mode = RuntimeMode::Hero;
let algo = Algorithm::new(
&client,
@ -659,7 +662,7 @@ Uptime = 0h 2m 4s
assert_eq!(algo.stats.target_donation_hashrate, 15382.1);
lock!(gui_api_p2pool).sidechain_ehr = 25000.0;
gui_api_p2pool.lock().unwrap().sidechain_ehr = 25000.0;
let algo = Algorithm::new(
&client,

View file

@ -46,10 +46,10 @@ impl Helper {
let mut i = 0;
while let Some(Ok(line)) = stdout.next() {
let line = strip_ansi_escapes::strip_str(line);
if let Err(e) = writeln!(lock!(output_parse), "{}", line) {
if let Err(e) = writeln!(output_parse.lock().unwrap(), "{}", line) {
error!("XMRig PTY Parse | Output error: {}", e);
}
if let Err(e) = writeln!(lock!(output_pub), "{}", line) {
if let Err(e) = writeln!(output_pub.lock().unwrap(), "{}", line) {
error!("XMRig PTY Pub | Output error: {}", e);
}
if i > 13 {
@ -63,9 +63,9 @@ impl Helper {
// need to verify if node still working
// for that need to catch "connect error"
// only check if xvb process is used and xmrig-proxy is not.
if lock!(process_xvb).is_alive() && !lock!(process_xp).is_alive() {
if process_xvb.lock().unwrap().is_alive() && !process_xp.lock().unwrap().is_alive() {
if contains_error(&line) {
let current_node = lock!(pub_api_xvb).current_node;
let current_node = pub_api_xvb.lock().unwrap().current_node;
if let Some(current_node) = current_node {
// updating current node to None, will stop sending signal of FailedNode until new node is set
// send signal to update node.
@ -73,9 +73,10 @@ impl Helper {
// update nodes only if we were not mining on p2pool.
// if xmrig stop, xvb will react in any case.
if current_node != XvbNode::P2pool {
lock!(process_xvb).signal = ProcessSignal::UpdateNodes(current_node);
process_xvb.lock().unwrap().signal =
ProcessSignal::UpdateNodes(current_node);
}
lock!(pub_api_xvb).current_node = None;
pub_api_xvb.lock().unwrap().current_node = None;
}
}
if contains_usepool(&line) {
@ -86,16 +87,17 @@ impl Helper {
if node.is_none() {
error!("XMRig PTY Parse | node is not understood, switching to backup.");
// update with default will choose which XvB to prefer. Will update XvB to use p2pool.
lock!(process_xvb).signal = ProcessSignal::UpdateNodes(XvbNode::default());
process_xvb.lock().unwrap().signal =
ProcessSignal::UpdateNodes(XvbNode::default());
}
lock!(pub_api_xvb).current_node = node;
pub_api_xvb.lock().unwrap().current_node = node;
}
}
// println!("{}", line); // For debugging.
if let Err(e) = writeln!(lock!(output_parse), "{}", line) {
if let Err(e) = writeln!(output_parse.lock().unwrap(), "{}", line) {
error!("XMRig PTY Parse | Output error: {}", e);
}
if let Err(e) = writeln!(lock!(output_pub), "{}", line) {
if let Err(e) = writeln!(output_pub.lock().unwrap(), "{}", line) {
error!("XMRig PTY Pub | Output error: {}", e);
}
}
@ -117,7 +119,7 @@ impl Helper {
// Write the [sudo] password to STDIN.
let mut stdin = child.stdin.take().unwrap();
use std::io::Write;
if let Err(e) = writeln!(stdin, "{}\n", lock!(sudo).pass) {
if let Err(e) = writeln!(stdin, "{}\n", sudo.lock().unwrap().pass) {
error!("Sudo Kill | STDIN error: {}", e);
}
@ -130,12 +132,12 @@ impl Helper {
// Just sets some signals for the watchdog thread to pick up on.
pub fn stop_xmrig(helper: &Arc<Mutex<Self>>) {
info!("XMRig | Attempting to stop...");
lock2!(helper, xmrig).signal = ProcessSignal::Stop;
lock2!(helper, xmrig).state = ProcessState::Middle;
let gui_api = Arc::clone(&lock!(helper).gui_api_xmrig);
let pub_api = Arc::clone(&lock!(helper).pub_api_xmrig);
*lock!(pub_api) = PubXmrigApi::new();
*lock!(gui_api) = PubXmrigApi::new();
helper.lock().unwrap().xmrig.lock().unwrap().signal = ProcessSignal::Stop;
helper.lock().unwrap().xmrig.lock().unwrap().state = ProcessState::Middle;
let gui_api = Arc::clone(&helper.lock().unwrap().gui_api_xmrig);
let pub_api = Arc::clone(&helper.lock().unwrap().pub_api_xmrig);
*pub_api.lock().unwrap() = PubXmrigApi::new();
*gui_api.lock().unwrap() = PubXmrigApi::new();
}
#[cold]
@ -149,15 +151,15 @@ impl Helper {
sudo: Arc<Mutex<SudoState>>,
) {
info!("XMRig | Attempting to restart...");
lock2!(helper, xmrig).signal = ProcessSignal::Restart;
lock2!(helper, xmrig).state = ProcessState::Middle;
helper.lock().unwrap().xmrig.lock().unwrap().signal = ProcessSignal::Restart;
helper.lock().unwrap().xmrig.lock().unwrap().state = ProcessState::Middle;
let helper = Arc::clone(helper);
let state = state.clone();
let path = path.to_path_buf();
// This thread lives to wait, start xmrig then die.
thread::spawn(move || {
while lock2!(helper, xmrig).state != ProcessState::Waiting {
while helper.lock().unwrap().xmrig.lock().unwrap().state != ProcessState::Waiting {
warn!("XMRig | Want to restart but process is still alive, waiting...");
sleep!(1000);
}
@ -176,7 +178,7 @@ impl Helper {
path: &Path,
sudo: Arc<Mutex<SudoState>>,
) {
lock2!(helper, xmrig).state = ProcessState::Middle;
helper.lock().unwrap().xmrig.lock().unwrap().state = ProcessState::Middle;
let (args, api_ip_port) = Self::build_xmrig_args_and_mutate_img(helper, state, path);
// Print arguments & user settings to console
@ -184,15 +186,15 @@ impl Helper {
info!("XMRig | Using path: [{}]", path.display());
// Spawn watchdog thread
let process = Arc::clone(&lock!(helper).xmrig);
let gui_api = Arc::clone(&lock!(helper).gui_api_xmrig);
let pub_api = Arc::clone(&lock!(helper).pub_api_xmrig);
let process_xvb = Arc::clone(&lock!(helper).xvb);
let process_xp = Arc::clone(&lock!(helper).xmrig_proxy);
let process = Arc::clone(&helper.lock().unwrap().xmrig);
let gui_api = Arc::clone(&helper.lock().unwrap().gui_api_xmrig);
let pub_api = Arc::clone(&helper.lock().unwrap().pub_api_xmrig);
let process_xvb = Arc::clone(&helper.lock().unwrap().xvb);
let process_xp = Arc::clone(&helper.lock().unwrap().xmrig_proxy);
let path = path.to_path_buf();
let token = state.token.clone();
let img_xmrig = Arc::clone(&lock!(helper).img_xmrig);
let pub_api_xvb = Arc::clone(&lock!(helper).pub_api_xvb);
let img_xmrig = Arc::clone(&helper.lock().unwrap().img_xmrig);
let pub_api_xvb = Arc::clone(&helper.lock().unwrap().pub_api_xvb);
thread::spawn(move || {
Self::spawn_xmrig_watchdog(
process,
@ -258,12 +260,13 @@ impl Helper {
args.push("--pause-on-active".to_string());
args.push(state.pause.to_string());
} // Pause on active
*lock2!(helper, img_xmrig) = ImgXmrig {
*helper.lock().unwrap().img_xmrig.lock().unwrap() = ImgXmrig {
threads: state.current_threads.to_string(),
url: "127.0.0.1:3333 (Local P2Pool)".to_string(),
};
lock2!(helper, pub_api_xmrig).node = "127.0.0.1:3333 (Local P2Pool)".to_string();
helper.lock().unwrap().pub_api_xmrig.lock().unwrap().node =
"127.0.0.1:3333 (Local P2Pool)".to_string();
api_ip = "127.0.0.1".to_string();
api_port = "18088".to_string();
@ -274,8 +277,8 @@ impl Helper {
// This parses the input and attempts to fill out
// the [ImgXmrig]... This is pretty bad code...
let mut last = "";
let lock = lock!(helper);
let mut xmrig_image = lock!(lock.img_xmrig);
let lock = helper.lock().unwrap();
let mut xmrig_image = lock.img_xmrig.lock().unwrap();
for arg in state.arguments.split_whitespace() {
match last {
"--threads" => xmrig_image.threads = arg.to_string(),
@ -339,11 +342,11 @@ impl Helper {
args.push("--pause-on-active".to_string());
args.push(state.pause.to_string());
} // Pause on active
*lock2!(helper, img_xmrig) = ImgXmrig {
*helper.lock().unwrap().img_xmrig.lock().unwrap() = ImgXmrig {
url: url.clone(),
threads: state.current_threads.to_string(),
};
lock2!(helper, pub_api_xmrig).node = url;
helper.lock().unwrap().pub_api_xmrig.lock().unwrap().node = url;
}
}
args.push(format!("--http-access-token={}", state.token)); // HTTP API Port
@ -404,8 +407,8 @@ impl Helper {
// 4. Spawn PTY read thread
debug!("XMRig | Spawning PTY read thread...");
let reader = pair.master.try_clone_reader().unwrap(); // Get STDOUT/STDERR before moving the PTY
let output_parse = Arc::clone(&lock!(process).output_parse);
let output_pub = Arc::clone(&lock!(process).output_pub);
let output_parse = Arc::clone(&process.lock().unwrap().output_parse);
let output_pub = Arc::clone(&process.lock().unwrap().output_pub);
spawn(enclose!((pub_api_xvb, process_xp) async move {
Self::read_pty_xmrig(output_parse, output_pub, reader, process_xvb, process_xp, &pub_api_xvb).await;
}));
@ -428,19 +431,19 @@ impl Helper {
// a) Sleep to wait for [sudo]'s non-echo prompt (on Unix).
// this prevents users pass from showing up in the STDOUT.
sleep!(3000);
if let Err(e) = writeln!(stdin, "{}", lock!(sudo).pass) {
if let Err(e) = writeln!(stdin, "{}", sudo.lock().unwrap().pass) {
error!("XMRig | Sudo STDIN error: {}", e);
};
SudoState::wipe(&sudo);
// b) Reset GUI STDOUT just in case.
debug!("XMRig | Clearing GUI output...");
lock!(gui_api).output.clear();
gui_api.lock().unwrap().output.clear();
}
// 3. Set process state
debug!("XMRig | Setting process state...");
let mut lock = lock!(process);
let mut lock = process.lock().unwrap();
lock.state = ProcessState::NotMining;
lock.signal = ProcessSignal::None;
lock.start = Instant::now();
@ -448,16 +451,16 @@ impl Helper {
// // 4. Spawn PTY read thread
// debug!("XMRig | Spawning PTY read thread...");
// let output_parse = Arc::clone(&lock!(process).output_parse);
// let output_pub = Arc::clone(&lock!(process).output_pub);
// let output_parse = Arc::clone(&process.lock().unwrap().output_parse);
// let output_pub = Arc::clone(&process.lock().unwrap().output_pub);
// spawn(enclose!((pub_api_xvb) async move {
// Self::read_pty_xmrig(output_parse, output_pub, reader, process_xvb, &pub_api_xvb).await;
// }));
let output_parse = Arc::clone(&lock!(process).output_parse);
let output_pub = Arc::clone(&lock!(process).output_pub);
let output_parse = Arc::clone(&process.lock().unwrap().output_parse);
let output_pub = Arc::clone(&process.lock().unwrap().output_pub);
let client = Client::new();
let start = lock!(process).start;
let start = process.lock().unwrap().start;
let api_uri = {
if !api_ip_port.ends_with('/') {
api_ip_port.push('/');
@ -467,10 +470,14 @@ impl Helper {
info!("XMRig | Final API URI: {}", api_uri);
// Reset stats before loop
*lock!(pub_api) = PubXmrigApi::new();
*lock!(gui_api) = PubXmrigApi::new();
*pub_api.lock().unwrap() = PubXmrigApi::new();
*gui_api.lock().unwrap() = PubXmrigApi::new();
// node used for process Status tab
lock!(gui_api).node.clone_from(&lock!(img_xmrig).url);
gui_api
.lock()
.unwrap()
.node
.clone_from(&img_xmrig.lock().unwrap().url);
// 5. Loop as watchdog
info!("XMRig | Entering watchdog mode... woof!");
// needs xmrig to be in belownormal priority or else Gupaxx will be in trouble if it does not have enough cpu time.
@ -499,9 +506,9 @@ impl Helper {
// Check if the process secretly died without us knowing :)
if check_died(
&child_pty,
&mut lock!(process),
&mut process.lock().unwrap(),
&start,
&mut lock!(gui_api).output,
&mut gui_api.lock().unwrap().output,
) {
break;
}
@ -510,7 +517,7 @@ impl Helper {
&process,
&child_pty,
&start,
&mut lock!(gui_api).output,
&mut gui_api.lock().unwrap().output,
&sudo,
) {
break;
@ -520,7 +527,7 @@ impl Helper {
// Check if logs need resetting
debug!("XMRig Watchdog | Attempting GUI log reset check");
{
let mut lock = lock!(gui_api);
let mut lock = gui_api.lock().unwrap();
Self::check_reset_gui_output(&mut lock.output, ProcessName::Xmrig);
}
// Always update from output
@ -547,8 +554,8 @@ impl Helper {
}
}
// if mining on proxy and proxy is not alive, switch back to p2pool node
if lock!(gui_api).node == XvbNode::XmrigProxy.to_string()
&& !lock!(process_xp).is_alive()
if gui_api.lock().unwrap().node == XvbNode::XmrigProxy.to_string()
&& !process_xp.lock().unwrap().is_alive()
{
info!("XMRig Process | redirect xmrig to p2pool since XMRig-Proxy is not alive anymore");
if let Err(err) = update_xmrig_config(
@ -564,7 +571,7 @@ impl Helper {
// show to console error about updating xmrig config
warn!("XMRig Process | Failed request HTTP API Xmrig");
output_console(
&mut lock!(gui_api).output,
&mut gui_api.lock().unwrap().output,
&format!(
"Failure to update xmrig config with HTTP API.\nError: {}",
err
@ -572,7 +579,7 @@ impl Helper {
ProcessName::Xmrig,
);
} else {
lock!(gui_api).node = XvbNode::P2pool.to_string();
gui_api.lock().unwrap().node = XvbNode::P2pool.to_string();
debug!("XMRig Process | mining on P2Pool pool");
}
}
@ -590,7 +597,7 @@ impl Helper {
gui_api_output_raw: &mut String,
sudo: &Arc<Mutex<SudoState>>,
) -> bool {
let signal = lock!(process).signal;
let signal = process.lock().unwrap().signal;
if signal == ProcessSignal::Stop || signal == ProcessSignal::Restart {
debug!("XMRig Watchdog | Stop/Restart SIGNAL caught");
// macOS requires [sudo] again to kill [XMRig]
@ -598,18 +605,18 @@ impl Helper {
// If we're at this point, that means the user has
// entered their [sudo] pass again, after we wiped it.
// So, we should be able to find it in our [Arc<Mutex<SudoState>>].
Self::sudo_kill(lock!(child_pty).process_id().unwrap(), sudo);
Self::sudo_kill(child_pty.lock().unwrap().process_id().unwrap(), sudo);
// And... wipe it again (only if we're stopping full).
// If we're restarting, the next start will wipe it for us.
if signal != ProcessSignal::Restart {
SudoState::wipe(sudo);
}
} else if let Err(e) = lock!(child_pty).kill() {
} else if let Err(e) = child_pty.lock().unwrap().kill() {
error!("XMRig Watchdog | Kill error: {}", e);
}
let exit_status = match lock!(child_pty).wait() {
let exit_status = match child_pty.lock().unwrap().wait() {
Ok(e) => {
let mut process = lock!(process);
let mut process = process.lock().unwrap();
if e.success() {
if process.signal == ProcessSignal::Stop {
process.state = ProcessState::Dead;
@ -623,7 +630,7 @@ impl Helper {
}
}
_ => {
let mut process = lock!(process);
let mut process = process.lock().unwrap();
if process.signal == ProcessSignal::Stop {
process.state = ProcessState::Failed;
}
@ -645,7 +652,7 @@ impl Helper {
e
);
}
let mut process = lock!(process);
let mut process = process.lock().unwrap();
match process.signal {
ProcessSignal::Stop => process.signal = ProcessSignal::None,
ProcessSignal::Restart => process.state = ProcessState::Waiting,
@ -746,10 +753,10 @@ impl PubXmrigApi {
process: &Arc<Mutex<Process>>,
) {
// 1. Take the process's current output buffer and combine it with Pub (if not empty)
let mut output_pub = lock!(output_pub);
let mut output_pub = output_pub.lock().unwrap();
{
let mut public = lock!(public);
let mut public = public.lock().unwrap();
if !output_pub.is_empty() {
public.output.push_str(&std::mem::take(&mut *output_pub));
}
@ -758,11 +765,11 @@ impl PubXmrigApi {
}
// 2. Check for "new job"/"no active...".
let mut output_parse = lock!(output_parse);
let mut output_parse = output_parse.lock().unwrap();
if XMRIG_REGEX.new_job.is_match(&output_parse) {
lock!(process).state = ProcessState::Alive;
process.lock().unwrap().state = ProcessState::Alive;
} else if XMRIG_REGEX.not_mining.is_match(&output_parse) {
lock!(process).state = ProcessState::NotMining;
process.lock().unwrap().state = ProcessState::NotMining;
}
// 3. Throw away [output_parse]
@ -772,7 +779,7 @@ impl PubXmrigApi {
// Formats raw private data into ready-to-print human readable version.
fn update_from_priv(public: &Arc<Mutex<Self>>, private: PrivXmrigApi) {
let mut public = lock!(public);
let mut public = public.lock().unwrap();
let hashrate_raw = match private.hashrate.total.first() {
Some(Some(h)) => *h,
_ => 0.0,

View file

@ -19,7 +19,7 @@ use crate::{
xvb::{nodes::XvbNode, PubXvbApi},
Helper, Process, ProcessName, ProcessSignal, ProcessState,
},
macros::{arc_mut, lock, lock2, sleep},
macros::{arc_mut, sleep},
miscs::output_console,
regex::{contains_timeout, contains_usepool, detect_new_node_xmrig, XMRIG_REGEX},
GUPAX_VERSION_UNDERSCORE, UNKNOWN_DATA,
@ -46,10 +46,10 @@ impl Helper {
let mut i = 0;
while let Some(Ok(line)) = stdout.next() {
let line = strip_ansi_escapes::strip_str(line);
if let Err(e) = writeln!(lock!(output_parse), "{}", line) {
if let Err(e) = writeln!(output_parse.lock().unwrap(), "{}", line) {
error!("XMRig-Proxy PTY Parse | Output error: {}", e);
}
if let Err(e) = writeln!(lock!(output_pub), "{}", line) {
if let Err(e) = writeln!(output_pub.lock().unwrap(), "{}", line) {
error!("XMRig-Proxy PTY Pub | Output error: {}", e);
}
if i > 7 {
@ -63,9 +63,9 @@ impl Helper {
// need to verify if node still working
// for that need to catch "connect error"
// only switch nodes of XvB if XvB process is used
if lock!(process_xvb).is_alive() {
if process_xvb.lock().unwrap().is_alive() {
if contains_timeout(&line) {
let current_node = lock!(pub_api_xvb).current_node;
let current_node = pub_api_xvb.lock().unwrap().current_node;
if let Some(current_node) = current_node {
// updating current node to None, will stop sending signal of FailedNode until new node is set
// send signal to update node.
@ -73,9 +73,10 @@ impl Helper {
"XMRig-Proxy PTY Parse | node is offline, sending signal to update nodes."
);
if current_node != XvbNode::P2pool {
lock!(process_xvb).signal = ProcessSignal::UpdateNodes(current_node);
process_xvb.lock().unwrap().signal =
ProcessSignal::UpdateNodes(current_node);
}
lock!(pub_api_xvb).current_node = None;
pub_api_xvb.lock().unwrap().current_node = None;
}
}
if contains_usepool(&line) {
@ -89,16 +90,17 @@ impl Helper {
"XMRig-Proxy PTY Parse | node is not understood, switching to backup."
);
// update with default will choose which XvB to prefer. Will update XvB to use p2pool.
lock!(process_xvb).signal = ProcessSignal::UpdateNodes(XvbNode::default());
process_xvb.lock().unwrap().signal =
ProcessSignal::UpdateNodes(XvbNode::default());
}
lock!(pub_api_xvb).current_node = node;
pub_api_xvb.lock().unwrap().current_node = node;
}
}
// println!("{}", line); // For debugging.
if let Err(e) = writeln!(lock!(output_parse), "{}", line) {
if let Err(e) = writeln!(output_parse.lock().unwrap(), "{}", line) {
error!("XMRig-Proxy PTY Parse | Output error: {}", e);
}
if let Err(e) = writeln!(lock!(output_pub), "{}", line) {
if let Err(e) = writeln!(output_pub.lock().unwrap(), "{}", line) {
error!("XMRig-Proxy PTY Pub | Output error: {}", e);
}
}
@ -131,7 +133,8 @@ impl Helper {
args.push("127.0.0.1".to_string()); // HTTP API IP
args.push("--http-port".to_string());
args.push("18089".to_string()); // HTTP API Port
lock2!(helper, pub_api_xp).node = "127.0.0.1:3333 (Local P2Pool)".to_string();
helper.lock().unwrap().pub_api_xp.lock().unwrap().node =
"127.0.0.1:3333 (Local P2Pool)".to_string();
// [Advanced]
} else if !state.arguments.is_empty() {
@ -191,7 +194,7 @@ impl Helper {
if state.keepalive {
args.push("--keepalive".to_string());
} // Keepalive
lock2!(helper, pub_api_xp).node = p2pool_url;
helper.lock().unwrap().pub_api_xp.lock().unwrap().node = p2pool_url;
}
args.push(format!("--http-access-token={}", state.token)); // HTTP API Port
args.push("--http-no-restricted".to_string());
@ -200,17 +203,17 @@ impl Helper {
pub fn stop_xp(helper: &Arc<Mutex<Self>>) {
info!("XMRig-Proxy | Attempting to stop...");
lock2!(helper, xmrig_proxy).signal = ProcessSignal::Stop;
helper.lock().unwrap().xmrig_proxy.lock().unwrap().signal = ProcessSignal::Stop;
info!("locked signal ok");
lock2!(helper, xmrig_proxy).state = ProcessState::Middle;
helper.lock().unwrap().xmrig_proxy.lock().unwrap().state = ProcessState::Middle;
info!("locked state ok");
let gui_api = Arc::clone(&lock!(helper).gui_api_xp);
let gui_api = Arc::clone(&helper.lock().unwrap().gui_api_xp);
info!("clone gui ok");
let pub_api = Arc::clone(&lock!(helper).pub_api_xp);
let pub_api = Arc::clone(&helper.lock().unwrap().pub_api_xp);
info!("clone pub ok");
*lock!(pub_api) = PubXmrigProxyApi::new();
*pub_api.lock().unwrap() = PubXmrigProxyApi::new();
info!("pub api reset ok");
*lock!(gui_api) = PubXmrigProxyApi::new();
*gui_api.lock().unwrap() = PubXmrigProxyApi::new();
info!("gui api reset ok");
}
// The "restart frontend" to a "frontend" function.
@ -222,8 +225,8 @@ impl Helper {
path: &Path,
) {
info!("XMRig-Proxy | Attempting to restart...");
lock2!(helper, xmrig_proxy).state = ProcessState::Middle;
lock2!(helper, xmrig_proxy).signal = ProcessSignal::Restart;
helper.lock().unwrap().xmrig_proxy.lock().unwrap().state = ProcessState::Middle;
helper.lock().unwrap().xmrig_proxy.lock().unwrap().signal = ProcessSignal::Restart;
let helper = Arc::clone(helper);
let state = state.clone();
@ -231,7 +234,8 @@ impl Helper {
let path = path.to_path_buf();
// This thread lives to wait, start xmrig_proxy then die.
thread::spawn(move || {
while lock2!(helper, xmrig_proxy).state != ProcessState::Waiting {
while helper.lock().unwrap().xmrig_proxy.lock().unwrap().state != ProcessState::Waiting
{
warn!("XMRig-proxy | Want to restart but process is still alive, waiting...");
sleep!(1000);
}
@ -247,7 +251,7 @@ impl Helper {
state_xmrig: &Xmrig,
path: &Path,
) {
lock2!(helper, xmrig_proxy).state = ProcessState::Middle;
helper.lock().unwrap().xmrig_proxy.lock().unwrap().state = ProcessState::Middle;
let args = Self::build_xp_args(helper, state_proxy);
// Print arguments & user settings to console
@ -255,17 +259,17 @@ impl Helper {
info!("XMRig-Proxy | Using path: [{}]", path.display());
// Spawn watchdog thread
let process = Arc::clone(&lock!(helper).xmrig_proxy);
let gui_api = Arc::clone(&lock!(helper).gui_api_xp);
let pub_api = Arc::clone(&lock!(helper).pub_api_xp);
let process_xvb = Arc::clone(&lock!(helper).xvb);
let process_xmrig = Arc::clone(&lock!(helper).xmrig);
let process = Arc::clone(&helper.lock().unwrap().xmrig_proxy);
let gui_api = Arc::clone(&helper.lock().unwrap().gui_api_xp);
let pub_api = Arc::clone(&helper.lock().unwrap().pub_api_xp);
let process_xvb = Arc::clone(&helper.lock().unwrap().xvb);
let process_xmrig = Arc::clone(&helper.lock().unwrap().xmrig);
let path = path.to_path_buf();
let token = state_proxy.token.clone();
let state_xmrig = state_xmrig.clone();
let redirect_xmrig = state_proxy.redirect_local_xmrig;
let pub_api_xvb = Arc::clone(&lock!(helper).pub_api_xvb);
let gui_api_xmrig = Arc::clone(&lock!(helper).gui_api_xmrig);
let pub_api_xvb = Arc::clone(&helper.lock().unwrap().pub_api_xvb);
let gui_api_xmrig = Arc::clone(&helper.lock().unwrap().gui_api_xmrig);
thread::spawn(move || {
Self::spawn_xp_watchdog(
&process,
@ -300,7 +304,7 @@ impl Helper {
pub_api_xvb: &Arc<Mutex<PubXvbApi>>,
gui_api_xmrig: &Arc<Mutex<PubXmrigApi>>,
) {
lock!(process).start = Instant::now();
process.lock().unwrap().start = Instant::now();
// spawn pty
debug!("XMRig-Proxy | Creating PTY...");
let pty = portable_pty::native_pty_system();
@ -315,8 +319,8 @@ impl Helper {
// 4. Spawn PTY read thread
debug!("XMRig-Proxy | Spawning PTY read thread...");
let reader = pair.master.try_clone_reader().unwrap(); // Get STDOUT/STDERR before moving the PTY
let output_parse = Arc::clone(&lock!(process).output_parse);
let output_pub = Arc::clone(&lock!(process).output_pub);
let output_parse = Arc::clone(&process.lock().unwrap().output_parse);
let output_pub = Arc::clone(&process.lock().unwrap().output_pub);
spawn(enc!((pub_api_xvb, output_parse, output_pub) async move {
Self::read_pty_xp(output_parse, output_pub, reader, process_xvb, &pub_api_xvb).await;
}));
@ -336,15 +340,15 @@ impl Helper {
// set state
let client = Client::new();
lock!(process).state = ProcessState::NotMining;
lock!(process).signal = ProcessSignal::None;
process.lock().unwrap().state = ProcessState::NotMining;
process.lock().unwrap().signal = ProcessSignal::None;
// reset stats
let node = lock!(pub_api).node.to_string();
*lock!(pub_api) = PubXmrigProxyApi::new();
*lock!(gui_api) = PubXmrigProxyApi::new();
lock!(gui_api).node = node;
let node = pub_api.lock().unwrap().node.to_string();
*pub_api.lock().unwrap() = PubXmrigProxyApi::new();
*gui_api.lock().unwrap() = PubXmrigProxyApi::new();
gui_api.lock().unwrap().node = node;
// loop
let start = lock!(process).start;
let start = process.lock().unwrap().start;
debug!("Xmrig-Proxy Watchdog | enabling verbose mode");
#[cfg(target_os = "windows")]
if let Err(e) = write!(stdin, "v\r\n") {
@ -370,14 +374,19 @@ impl Helper {
// check state
if check_died(
&child_pty,
&mut lock!(process),
&mut process.lock().unwrap(),
&start,
&mut lock!(gui_api).output,
&mut gui_api.lock().unwrap().output,
) {
break;
}
// check signal
if signal_end(process, &child_pty, &start, &mut lock!(gui_api).output) {
if signal_end(
process,
&child_pty,
&start,
&mut gui_api.lock().unwrap().output,
) {
break;
}
// check user input
@ -387,7 +396,7 @@ impl Helper {
// Check if logs need resetting
debug!("XMRig-Proxy Watchdog | Attempting GUI log reset check");
{
let mut lock = lock!(gui_api);
let mut lock = gui_api.lock().unwrap();
Self::check_reset_gui_output(&mut lock.output, ProcessName::XmrigProxy);
}
// Always update from output
@ -416,9 +425,9 @@ impl Helper {
}
// update xmrig to use xmrig-proxy if option enabled and local xmrig alive
if xmrig_redirect
&& lock!(gui_api_xmrig).node != XvbNode::XmrigProxy.to_string()
&& (lock!(process_xmrig).state == ProcessState::Alive
|| lock!(process_xmrig).state == ProcessState::NotMining)
&& gui_api_xmrig.lock().unwrap().node != XvbNode::XmrigProxy.to_string()
&& (process_xmrig.lock().unwrap().state == ProcessState::Alive
|| process_xmrig.lock().unwrap().state == ProcessState::NotMining)
{
info!("redirect local xmrig instance to xmrig-proxy");
if let Err(err) = update_xmrig_config(
@ -434,7 +443,7 @@ impl Helper {
// show to console error about updating xmrig config
warn!("XMRig-Proxy Process | Failed request HTTP API Xmrig");
output_console(
&mut lock!(gui_api).output,
&mut gui_api.lock().unwrap().output,
&format!(
"Failure to update xmrig config with HTTP API.\nError: {}",
err
@ -442,7 +451,7 @@ impl Helper {
ProcessName::XmrigProxy,
);
} else {
lock!(gui_api_xmrig).node = XvbNode::XmrigProxy.to_string();
gui_api_xmrig.lock().unwrap().node = XvbNode::XmrigProxy.to_string();
debug!("XMRig-Proxy Process | mining on Xmrig-Proxy pool");
}
}
@ -497,10 +506,10 @@ impl PubXmrigProxyApi {
process: &Arc<Mutex<Process>>,
) {
// 1. Take the process's current output buffer and combine it with Pub (if not empty)
let mut output_pub = lock!(output_pub);
let mut output_pub = output_pub.lock().unwrap();
{
let mut public = lock!(public);
let mut public = public.lock().unwrap();
if !output_pub.is_empty() {
public.output.push_str(&std::mem::take(&mut *output_pub));
}
@ -509,16 +518,16 @@ impl PubXmrigProxyApi {
}
// 2. Check for "new job"/"no active...".
let mut output_parse = lock!(output_parse);
let mut output_parse = output_parse.lock().unwrap();
if XMRIG_REGEX.new_job.is_match(&output_parse)
|| XMRIG_REGEX.valid_conn.is_match(&output_parse)
{
lock!(process).state = ProcessState::Alive;
process.lock().unwrap().state = ProcessState::Alive;
} else if XMRIG_REGEX.timeout.is_match(&output_parse)
|| XMRIG_REGEX.invalid_conn.is_match(&output_parse)
|| XMRIG_REGEX.error.is_match(&output_parse)
{
lock!(process).state = ProcessState::NotMining;
process.lock().unwrap().state = ProcessState::NotMining;
}
// 3. Throw away [output_parse]
output_parse.clear();
@ -539,7 +548,7 @@ impl PubXmrigProxyApi {
}
}
fn update_from_priv(public: &Arc<Mutex<Self>>, private: PrivXmrigProxyApi) {
let mut public = lock!(public);
let mut public = public.lock().unwrap();
*public = Self {
accepted: private.results.accepted,
rejected: private.results.rejected,

View file

@ -18,7 +18,6 @@ use crate::{
xrig::{update_xmrig_config, xmrig::PubXmrigApi},
xvb::{nodes::XvbNode, priv_stats::RuntimeMode},
},
macros::lock,
BLOCK_PPLNS_WINDOW_MAIN, BLOCK_PPLNS_WINDOW_MINI, SECOND_PER_BLOCK_P2POOL,
XVB_ROUND_DONOR_MEGA_MIN_HR, XVB_ROUND_DONOR_MIN_HR, XVB_ROUND_DONOR_VIP_MIN_HR,
XVB_ROUND_DONOR_WHALE_MIN_HR, XVB_TIME_ALGO,
@ -119,24 +118,27 @@ impl<'a> Algorithm<'a> {
let address = state_p2pool.address.clone();
let runtime_mode = lock!(gui_api_xvb).stats_priv.runtime_mode.clone();
let runtime_donation_level = lock!(gui_api_xvb)
let runtime_mode = gui_api_xvb.lock().unwrap().stats_priv.runtime_mode.clone();
let runtime_donation_level = gui_api_xvb
.lock()
.unwrap()
.stats_priv
.runtime_manual_donation_level
.clone();
let runtime_amount = lock!(gui_api_xvb).stats_priv.runtime_manual_amount;
let runtime_amount = gui_api_xvb.lock().unwrap().stats_priv.runtime_manual_amount;
let p2pool_total_hashrate = lock!(gui_api_p2pool).sidechain_ehr;
let p2pool_total_hashrate = gui_api_p2pool.lock().unwrap().sidechain_ehr;
let avg_last_hour_hashrate =
Self::calc_last_hour_avg_hash_rate(&lock!(gui_api_xvb).p2pool_sent_last_hour_samples);
let avg_last_hour_hashrate = Self::calc_last_hour_avg_hash_rate(
&gui_api_xvb.lock().unwrap().p2pool_sent_last_hour_samples,
);
let mut p2pool_external_hashrate = p2pool_total_hashrate - avg_last_hour_hashrate;
if p2pool_external_hashrate < 0.0 {
p2pool_external_hashrate = 0.0;
}
let share_min_hashrate = Self::minimum_hashrate_share(
lock!(gui_api_p2pool).p2pool_difficulty_u64,
gui_api_p2pool.lock().unwrap().p2pool_difficulty_u64,
state_p2pool.mini,
p2pool_external_hashrate,
p2pool_buffer,
@ -149,8 +151,8 @@ impl<'a> Algorithm<'a> {
let msg_xmrig_or_xp = (if xp_alive { "XMRig-Proxy" } else { "XMRig" }).to_string();
info!("xp alive: {:?}", xp_alive);
let xvb_24h_avg = lock!(pub_api).stats_priv.donor_24hr_avg * 1000.0;
let xvb_1h_avg = lock!(pub_api).stats_priv.donor_1hr_avg * 1000.0;
let xvb_24h_avg = pub_api.lock().unwrap().stats_priv.donor_24hr_avg * 1000.0;
let xvb_1h_avg = pub_api.lock().unwrap().stats_priv.donor_1hr_avg * 1000.0;
let stats = Stats {
share,
@ -218,7 +220,7 @@ impl<'a> Algorithm<'a> {
}
async fn target_p2pool_node(&self) {
if lock!(self.gui_api_xvb).current_node != Some(XvbNode::P2pool) {
if self.gui_api_xvb.lock().unwrap().current_node != Some(XvbNode::P2pool) {
info!(
"Algorithm | request {} to mine on p2pool",
self.stats.msg_xmrig_or_xp
@ -239,7 +241,7 @@ impl<'a> Algorithm<'a> {
self.stats.msg_xmrig_or_xp
);
output_console(
&mut lock!(self.gui_api_xvb).output,
&mut self.gui_api_xvb.lock().unwrap().output,
&format!(
"Failure to update {} config with HTTP API.\nError: {}",
self.stats.msg_xmrig_or_xp, err
@ -256,15 +258,18 @@ impl<'a> Algorithm<'a> {
}
async fn target_xvb_node(&self) {
let node = lock!(self.gui_api_xvb).stats_priv.node;
let node = self.gui_api_xvb.lock().unwrap().stats_priv.node;
info!(
"Algorithm | request {} to mine on XvB",
self.stats.msg_xmrig_or_xp
);
if lock!(self.gui_api_xvb).current_node.is_none()
|| lock!(self.gui_api_xvb)
if self.gui_api_xvb.lock().unwrap().current_node.is_none()
|| self
.gui_api_xvb
.lock()
.unwrap()
.current_node
.as_ref()
.is_some_and(|n| n == &XvbNode::P2pool)
@ -285,7 +290,7 @@ impl<'a> Algorithm<'a> {
self.stats.msg_xmrig_or_xp
);
output_console(
&mut lock!(self.gui_api_xvb).output,
&mut self.gui_api_xvb.lock().unwrap().output,
&format!(
"Failure to update {} config with HTTP API.\nError: {}",
self.stats.msg_xmrig_or_xp, err
@ -294,9 +299,9 @@ impl<'a> Algorithm<'a> {
);
} else {
if self.xp_alive {
lock!(self.gui_api_xp).node = node.to_string();
self.gui_api_xp.lock().unwrap().node = node.to_string();
} else {
lock!(self.gui_api_xmrig).node = node.to_string();
self.gui_api_xmrig.lock().unwrap().node = node.to_string();
}
info!(
"Algorithm | {} mining on XvB pool",
@ -315,11 +320,15 @@ impl<'a> Algorithm<'a> {
);
sleep(Duration::from_secs(XVB_TIME_ALGO.into())).await;
lock!(self.gui_api_xvb)
self.gui_api_xvb
.lock()
.unwrap()
.p2pool_sent_last_hour_samples
.0
.push_back(lock!(self.gui_api_xmrig).hashrate_raw_15m);
lock!(self.gui_api_xvb)
.push_back(self.gui_api_xmrig.lock().unwrap().hashrate_raw_15m);
self.gui_api_xvb
.lock()
.unwrap()
.xvb_sent_last_hour_samples
.0
.push_back(0.0);
@ -334,11 +343,15 @@ impl<'a> Algorithm<'a> {
);
sleep(Duration::from_secs(XVB_TIME_ALGO.into())).await;
lock!(self.gui_api_xvb)
self.gui_api_xvb
.lock()
.unwrap()
.p2pool_sent_last_hour_samples
.0
.push_back(lock!(self.gui_api_xmrig).hashrate_raw_15m);
lock!(self.gui_api_xvb)
.push_back(self.gui_api_xmrig.lock().unwrap().hashrate_raw_15m);
self.gui_api_xvb
.lock()
.unwrap()
.xvb_sent_last_hour_samples
.0
.push_back(0.0);
@ -368,7 +381,9 @@ impl<'a> Algorithm<'a> {
);
sleep(Duration::from_secs(self.stats.spared_time.into())).await;
lock!(self.gui_api_xvb)
self.gui_api_xvb
.lock()
.unwrap()
.p2pool_sent_last_hour_samples
.0
.push_back(
@ -376,7 +391,9 @@ impl<'a> Algorithm<'a> {
* ((XVB_TIME_ALGO as f32 - self.stats.spared_time as f32)
/ XVB_TIME_ALGO as f32),
);
lock!(self.gui_api_xvb)
self.gui_api_xvb
.lock()
.unwrap()
.xvb_sent_last_hour_samples
.0
.push_back(
@ -496,7 +513,7 @@ impl<'a> Algorithm<'a> {
async fn fulfill_share(&self) {
output_console(
&mut lock!(self.gui_api_xvb).output,
&mut self.gui_api_xvb.lock().unwrap().output,
"There are no shares in p2pool. Sending all hashrate to p2pool!",
crate::helper::ProcessName::Xvb,
);
@ -508,21 +525,21 @@ impl<'a> Algorithm<'a> {
async fn fulfill_xvb_24_avg(&self) {
output_console(
&mut lock!(self.gui_api_xvb).output,
&mut self.gui_api_xvb.lock().unwrap().output,
"24H avg XvB target not achieved. Sending all hashrate to XvB!",
crate::helper::ProcessName::Xvb,
);
info!("Algorithm | 24H avg XvB target not achieved. Sending all hashrate to XvB!");
*lock!(self.time_donated) = XVB_TIME_ALGO;
*self.time_donated.lock().unwrap() = XVB_TIME_ALGO;
self.send_all_xvb().await
}
async fn fulfill_normal_cycles(&self) {
output_console(
&mut lock!(self.gui_api_xvb).output,
&mut self.gui_api_xvb.lock().unwrap().output,
&format!(
"There is a share in p2pool and 24H avg XvB is achieved. Sending {} seconds to XvB!",
self.stats.spared_time
@ -532,7 +549,7 @@ impl<'a> Algorithm<'a> {
info!("Algorithm | There is a share in p2pool and 24H avg XvB is achieved. Sending seconds {} to XvB!", self.stats.spared_time);
*lock!(self.time_donated) = self.stats.spared_time;
*self.time_donated.lock().unwrap() = self.stats.spared_time;
self.target_p2pool_node().await;
self.sleep_then_update_node_xmrig().await;
@ -540,7 +557,7 @@ impl<'a> Algorithm<'a> {
pub async fn run(&mut self) {
output_console(
&mut lock!(self.gui_api_xvb).output,
&mut self.gui_api_xvb.lock().unwrap().output,
"Algorithm of HR distribution started for the next 10 minutes.",
crate::helper::ProcessName::Xvb,
);
@ -557,7 +574,7 @@ impl<'a> Algorithm<'a> {
}
output_console_without_time(
&mut lock!(self.gui_api_xvb).output,
&mut self.gui_api_xvb.lock().unwrap().output,
"",
crate::helper::ProcessName::Xvb,
)

View file

@ -24,7 +24,7 @@ use crate::helper::xvb::rounds::round_type;
use crate::utils::constants::{XVB_PUBLIC_ONLY, XVB_TIME_ALGO};
use crate::{
helper::{ProcessSignal, ProcessState},
utils::macros::{lock, lock2, sleep},
utils::macros::sleep,
};
use self::nodes::XvbNode;
@ -44,8 +44,8 @@ impl Helper {
// Just sets some signals for the watchdog thread to pick up on.
pub fn stop_xvb(helper: &Arc<Mutex<Self>>) {
info!("XvB | Attempting to stop...");
lock2!(helper, xvb).signal = ProcessSignal::Stop;
lock2!(helper, xvb).state = ProcessState::Middle;
helper.lock().unwrap().xvb.lock().unwrap().signal = ProcessSignal::Stop;
helper.lock().unwrap().xvb.lock().unwrap().state = ProcessState::Middle;
}
pub fn restart_xvb(
helper: &Arc<Mutex<Self>>,
@ -55,8 +55,8 @@ impl Helper {
state_xp: &crate::disk::state::XmrigProxy,
) {
info!("XvB | Attempting to restart...");
lock2!(helper, xvb).signal = ProcessSignal::Restart;
lock2!(helper, xvb).state = ProcessState::Middle;
helper.lock().unwrap().xvb.lock().unwrap().signal = ProcessSignal::Restart;
helper.lock().unwrap().xvb.lock().unwrap().state = ProcessState::Middle;
let helper = helper.clone();
let state_xvb = state_xvb.clone();
let state_p2pool = state_p2pool.clone();
@ -64,7 +64,7 @@ impl Helper {
let state_xp = state_xp.clone();
// This thread lives to wait, start xmrig then die.
thread::spawn(move || {
while lock2!(helper, xvb).state != ProcessState::Waiting {
while helper.lock().unwrap().xvb.lock().unwrap().state != ProcessState::Waiting {
warn!("XvB | Want to restart but process is still alive, waiting...");
sleep!(1000);
}
@ -88,17 +88,17 @@ impl Helper {
info!("XvB | cloning helper arc fields");
// without xmrig alive, it doesn't make sense to use XvB.
// needed to see if it is alive. For XvB process to function completely, p2pool node must be alive to check the shares in the pplns window.
let gui_api = Arc::clone(&lock!(helper).gui_api_xvb);
let pub_api = Arc::clone(&lock!(helper).pub_api_xvb);
let process = Arc::clone(&lock!(helper).xvb);
let process_p2pool = Arc::clone(&lock!(helper).p2pool);
let gui_api_p2pool = Arc::clone(&lock!(helper).gui_api_p2pool);
let process_xmrig = Arc::clone(&lock!(helper).xmrig);
let process_xp = Arc::clone(&lock!(helper).xmrig_proxy);
let gui_api_xmrig = Arc::clone(&lock!(helper).gui_api_xmrig);
let pub_api_xmrig = Arc::clone(&lock!(helper).pub_api_xmrig);
let gui_api_xp = Arc::clone(&lock!(helper).gui_api_xp);
let pub_api_xp = Arc::clone(&lock!(helper).gui_api_xp);
let gui_api = Arc::clone(&helper.lock().unwrap().gui_api_xvb);
let pub_api = Arc::clone(&helper.lock().unwrap().pub_api_xvb);
let process = Arc::clone(&helper.lock().unwrap().xvb);
let process_p2pool = Arc::clone(&helper.lock().unwrap().p2pool);
let gui_api_p2pool = Arc::clone(&helper.lock().unwrap().gui_api_p2pool);
let process_xmrig = Arc::clone(&helper.lock().unwrap().xmrig);
let process_xp = Arc::clone(&helper.lock().unwrap().xmrig_proxy);
let gui_api_xmrig = Arc::clone(&helper.lock().unwrap().gui_api_xmrig);
let pub_api_xmrig = Arc::clone(&helper.lock().unwrap().pub_api_xmrig);
let gui_api_xp = Arc::clone(&helper.lock().unwrap().gui_api_xp);
let pub_api_xp = Arc::clone(&helper.lock().unwrap().gui_api_xp);
// Reset before printing to output.
// Need to reset because values of stats would stay otherwise which could bring confusion even if panel is with a disabled theme.
// at the start of a process, values must be default.
@ -107,14 +107,14 @@ impl Helper {
);
reset_data_xvb(&pub_api, &gui_api);
// we reset the console output because it is complete start.
lock!(gui_api).output.clear();
gui_api.lock().unwrap().output.clear();
// 2. Set process state
// XvB has not yet decided if it can continue.
// it could fail if XvB server is offline or start partially if token/address is invalid or if p2pool or xmrig are offline.
// this state will be received accessed by the UI directly and put the status on yellow.
info!("XvB | Setting process state...");
{
let mut lock = lock!(process);
let mut lock = process.lock().unwrap();
lock.state = ProcessState::Middle;
lock.signal = ProcessSignal::None;
lock.start = std::time::Instant::now();
@ -188,7 +188,7 @@ impl Helper {
.await;
let mut xp_alive = false;
// uptime for log of signal check ?
let start = lock!(process).start;
let start = process.lock().unwrap().start;
// uptime of last run of algo
let last_algorithm = Arc::new(Mutex::new(tokio::time::Instant::now()));
// uptime of last request (public and private)
@ -210,9 +210,9 @@ impl Helper {
let start_loop = std::time::Instant::now();
// check if first loop the state of Xmrig-Proxy
if first_loop {
xp_alive = lock!(process_xp).state == ProcessState::Alive;
xp_alive = process_xp.lock().unwrap().state == ProcessState::Alive;
msg_retry_done = false;
*lock!(retry) = false;
*retry.lock().unwrap() = false;
}
// verify if p2pool and xmrig are running, else XvB must be reloaded with another token/address to start verifying the other process.
if check_state_outcauses_xvb(
@ -255,26 +255,31 @@ impl Helper {
info!("XvB Watchdog | Signal has stopped the loop");
break;
}
// let handle_algo_c = lock!(handle_algo);
let is_algo_started_once = lock!(handle_algo).is_some();
let is_algo_finished = lock!(handle_algo)
// let handle_algo_c = handle_algo.lock().unwrap();
let is_algo_started_once = handle_algo.lock().unwrap().is_some();
let is_algo_finished = handle_algo
.lock()
.unwrap()
.as_ref()
.is_some_and(|algo| algo.is_finished());
let is_request_finished = lock!(handle_request)
let is_request_finished = handle_request
.lock()
.unwrap()
.as_ref()
.is_some_and(|request: &JoinHandle<()>| request.is_finished())
|| lock!(handle_request).is_none();
|| handle_request.lock().unwrap().is_none();
// Send an HTTP API request only if one minute is passed since the last request or if first loop or if algorithm need to retry or if request is finished and algo is finished or almost finished (only public and private stats). We make sure public and private stats are refreshed before doing another run of the algo.
// We make sure algo or request are not rerun when they are not over.
// in the case of quick refresh before new run of algo, make sure it doesn't happen multiple times.
let last_request_expired = lock!(last_request).elapsed() >= Duration::from_secs(60);
let last_request_expired =
last_request.lock().unwrap().elapsed() >= Duration::from_secs(60);
let should_refresh_before_next_algo = is_algo_started_once
&& lock!(last_algorithm).elapsed()
&& last_algorithm.lock().unwrap().elapsed()
>= Duration::from_secs((XVB_TIME_ALGO as f32 * 0.95) as u64)
&& lock!(last_request).elapsed() >= Duration::from_secs(25);
let process_alive = lock!(process).state == ProcessState::Alive;
&& last_request.lock().unwrap().elapsed() >= Duration::from_secs(25);
let process_alive = process.lock().unwrap().state == ProcessState::Alive;
if ((last_request_expired || first_loop)
|| (*lock!(retry) || is_algo_finished || should_refresh_before_next_algo)
|| (*retry.lock().unwrap() || is_algo_finished || should_refresh_before_next_algo)
&& process_alive)
&& is_request_finished
{
@ -282,19 +287,19 @@ impl Helper {
// Private API will also use this instant if XvB is Alive.
// first_loop is false here but could be changed to true under some conditions.
// will send a stop signal if public stats failed or update data with new one.
*lock!(handle_request) = Some(spawn(
*handle_request.lock().unwrap() = Some(spawn(
enc!((client, pub_api, gui_api, gui_api_p2pool, gui_api_xmrig, gui_api_xp, state_xvb, state_p2pool, state_xmrig, state_xp, process, last_algorithm, retry, handle_algo, time_donated, last_request) async move {
// needs to wait here for public stats to get private stats.
if last_request_expired || first_loop || should_refresh_before_next_algo {
XvbPubStats::update_stats(&client, &gui_api, &pub_api, &process).await;
*lock!(last_request) = Instant::now();
*last_request.lock().unwrap() = Instant::now();
}
// private stats needs valid token and address.
// other stats needs everything to be alive, so just require alive here for now.
// maybe later differentiate to add a way to get private stats without running the algo ?
if lock!(process).state == ProcessState::Alive {
if process.lock().unwrap().state == ProcessState::Alive {
// get current share to know if we are in a round and this is a required data for algo.
let share = lock!(gui_api_p2pool).sidechain_shares;
let share = gui_api_p2pool.lock().unwrap().sidechain_shares;
debug!("XvB | Number of current shares: {}", share);
// private stats can be requested every minute or first loop or if the have almost finished.
if last_request_expired || first_loop || should_refresh_before_next_algo {
@ -304,29 +309,29 @@ impl Helper {
&client, &state_p2pool.address, &state_xvb.token, &pub_api, &gui_api, &process,
)
.await;
*lock!(last_request) = Instant::now();
*last_request.lock().unwrap() = Instant::now();
// verify in which round type we are
let round = round_type(share, &pub_api);
// refresh the round we participate in.
debug!("XvB | Round type: {:#?}", round);
lock!(pub_api).stats_priv.round_participate = round;
pub_api.lock().unwrap().stats_priv.round_participate = round;
// verify if we are the winner of the current round
if lock!(pub_api).stats_pub.winner
if pub_api.lock().unwrap().stats_pub.winner
== Helper::head_tail_of_monero_address(&state_p2pool.address).as_str()
{
lock!(pub_api).stats_priv.win_current = true
pub_api.lock().unwrap().stats_priv.win_current = true
}
}
let hashrate = current_controllable_hr(xp_alive, &gui_api_xp, &gui_api_xmrig);
let difficulty_data_is_ready = lock!(gui_api_p2pool).p2pool_difficulty_u64 > 100_000;
if (first_loop || *lock!(retry)|| is_algo_finished) && hashrate > 0.0 && lock!(process).state == ProcessState::Alive && difficulty_data_is_ready
let difficulty_data_is_ready = gui_api_p2pool.lock().unwrap().p2pool_difficulty_u64 > 100_000;
if (first_loop || *retry.lock().unwrap()|| is_algo_finished) && hashrate > 0.0 && process.lock().unwrap().state == ProcessState::Alive && difficulty_data_is_ready
{
// if algo was started, it must not retry next loop.
*lock!(retry) = false;
*retry.lock().unwrap() = false;
// reset instant because algo will start.
*lock!(last_algorithm) = Instant::now();
*lock!(handle_algo) = Some(spawn(enc!((client, gui_api, gui_api_xmrig, gui_api_xp, state_xmrig, state_xp, time_donated, state_xvb) async move {
*last_algorithm.lock().unwrap() = Instant::now();
*handle_algo.lock().unwrap() = Some(spawn(enc!((client, gui_api, gui_api_xmrig, gui_api_xp, state_xmrig, state_xp, time_donated, state_xvb) async move {
let token_xmrig = if xp_alive {
&state_xp.token
} else {
@ -356,8 +361,8 @@ impl Helper {
} else {
// if xmrig is still at 0 HR but is alive and algorithm is skipped, recheck first 10s of xmrig inside algorithm next time (in one minute). Don't check if algo failed to start because state was not alive after getting private stats.
if (hashrate == 0.0 || !difficulty_data_is_ready) && lock!(process).state == ProcessState::Alive {
*lock!(retry) = true
if (hashrate == 0.0 || !difficulty_data_is_ready) && process.lock().unwrap().state == ProcessState::Alive {
*retry.lock().unwrap() = true
}
}
@ -366,18 +371,18 @@ impl Helper {
));
}
// if retry is false, next time the message about waiting for xmrig HR can be shown.
if !*lock!(retry) {
if !*retry.lock().unwrap() {
msg_retry_done = false;
}
// inform user that algorithm has not yet started because it is waiting for xmrig HR.
// show this message only once before the start of algo
if *lock!(retry) && !msg_retry_done {
if *retry.lock().unwrap() && !msg_retry_done {
let msg = if xp_alive {
"Algorithm is waiting for 1 minute average HR of XMRig-Proxy or p2pool data"
} else {
"Algorithm is waiting for 10 seconds average HR of XMRig or p2pool data"
};
output_console(&mut lock!(gui_api).output, msg, ProcessName::Xvb);
output_console(&mut gui_api.lock().unwrap().output, msg, ProcessName::Xvb);
msg_retry_done = true;
}
// update indicator (time before switch and mining location) in private stats
@ -392,7 +397,7 @@ impl Helper {
is_algo_finished,
process,
pub_api,
*lock!(time_donated),
*time_donated.lock().unwrap(),
&last_algorithm,
);
// first_loop is done, but maybe retry will allow the algorithm to retry again.
@ -483,27 +488,27 @@ async fn check_conditions_for_start(
info!("XvB | verify address and token");
// send to console: token non existent for address on XvB server
warn!("Xvb | Start ... Partially failed because token and associated address are not existent on XvB server: {}\n", err);
output_console(&mut lock!(gui_api).output, &format!("Token and associated address are not valid on XvB API.\nCheck if you are registered.\nError: {}", err), ProcessName::Xvb);
output_console(&mut gui_api.lock().unwrap().output, &format!("Token and associated address are not valid on XvB API.\nCheck if you are registered.\nError: {}", err), ProcessName::Xvb);
ProcessState::NotMining
} else if lock!(process_p2pool).state != ProcessState::Alive {
} else if process_p2pool.lock().unwrap().state != ProcessState::Alive {
info!("XvB | verify p2pool node");
// send to console: p2pool process is not running
warn!("Xvb | Start ... Partially failed because P2pool instance is not ready.");
let msg = if lock!(process_p2pool).state == ProcessState::Syncing {
let msg = if process_p2pool.lock().unwrap().state == ProcessState::Syncing {
"P2pool process is not ready.\nCheck the P2pool Tab"
} else {
"P2pool process is not running.\nCheck the P2pool Tab"
};
output_console(&mut lock!(gui_api).output, msg, ProcessName::Xvb);
output_console(&mut gui_api.lock().unwrap().output, msg, ProcessName::Xvb);
ProcessState::Syncing
} else if lock!(process_xmrig).state != ProcessState::Alive
&& lock!(process_xp).state != ProcessState::Alive
} else if process_xmrig.lock().unwrap().state != ProcessState::Alive
&& process_xp.lock().unwrap().state != ProcessState::Alive
{
// send to console: xmrig process is not running
warn!("Xvb | Start ... Partially failed because Xmrig or Xmrig-Proxy instance is not running.");
// output the error to console
output_console(
&mut lock!(gui_api).output,
&mut gui_api.lock().unwrap().output,
"XMRig or Xmrig-Proxy process is not running.\nCheck the Xmrig or Xmrig-Proxy Tab. One of them must be running to start the XvB algorithm.",
ProcessName::Xvb,
);
@ -517,14 +522,14 @@ async fn check_conditions_for_start(
// while waiting for xmrig and p2pool or getting right address/token, it can get public stats
info!("XvB | print to console state");
output_console(
&mut lock!(gui_api).output,
&mut gui_api.lock().unwrap().output,
&["XvB partially started.\n", XVB_PUBLIC_ONLY].concat(),
ProcessName::Xvb,
);
}
// will update the preferred node for the first loop, even if partially started.
lock!(process_xvb).signal = ProcessSignal::UpdateNodes(XvbNode::default());
lock!(process_xvb).state = state;
process_xvb.lock().unwrap().signal = ProcessSignal::UpdateNodes(XvbNode::default());
process_xvb.lock().unwrap().state = state;
}
/// return a bool to continue to next loop if needed.
#[allow(clippy::too_many_arguments)]
@ -547,18 +552,18 @@ async fn check_state_outcauses_xvb(
) -> bool {
// will check if the state can stay as it is.
// p2pool and xmrig are alive if ready and running (syncing is not alive).
let state = lock!(process).state;
let state = process.lock().unwrap().state;
let xp_is_alive = lock!(process_xp).state == ProcessState::Alive;
let xp_is_alive = process_xp.lock().unwrap().state == ProcessState::Alive;
let msg_xmrig_or_proxy = if xp_is_alive { "Xmrig-Proxy" } else { "Xmrig" };
// if state is not alive, the algo should stop if it was running and p2pool should be used by xmrig.
if let Some(handle) = lock!(handle_algo).as_ref() {
if let Some(handle) = handle_algo.lock().unwrap().as_ref() {
// XvB should stop the algo if the state of xp is different from the start.
if xp_is_alive != xp_start_alive && !handle.is_finished() {
warn!("XvB Process | stop the algorithm because Xmrig-Proxy state changed");
output_console(
&mut lock!(gui_api).output,
&mut gui_api.lock().unwrap().output,
"Algorithm stopped because Xmrig-Proxy state changed",
ProcessName::Xvb,
);
@ -567,13 +572,13 @@ async fn check_state_outcauses_xvb(
if state != ProcessState::Alive && !handle.is_finished() {
handle.abort();
output_console(
&mut lock!(gui_api).output,
&mut gui_api.lock().unwrap().output,
"XvB process can not completely continue, algorithm of distribution of HR is stopped.",
ProcessName::Xvb
);
// only update xmrig if it is alive and wasn't on p2pool already.
if lock!(gui_api).current_node != Some(XvbNode::P2pool)
&& (lock!(process_xmrig).state == ProcessState::Alive || xp_is_alive)
if gui_api.lock().unwrap().current_node != Some(XvbNode::P2pool)
&& (process_xmrig.lock().unwrap().state == ProcessState::Alive || xp_is_alive)
{
let token_xmrig = if xp_is_alive {
state_xp.token.clone()
@ -601,7 +606,7 @@ async fn check_state_outcauses_xvb(
{
// show to console error about updating xmrig config
output_console(
&mut lock!(gui_api).output,
&mut gui_api.lock().unwrap().output,
&format!(
"Failure to update {msg_xmrig_or_proxy} config with HTTP API.\nError: {}",
err
@ -609,10 +614,10 @@ async fn check_state_outcauses_xvb(
ProcessName::Xvb
);
} else {
if xp_is_alive {lock!(pub_api_xp).node = XvbNode::P2pool.to_string();} else {lock!(pub_api_xmrig).node = XvbNode::P2pool.to_string();}
if xp_is_alive {pub_api_xp.lock().unwrap().node = XvbNode::P2pool.to_string();} else {pub_api_xmrig.lock().unwrap().node = XvbNode::P2pool.to_string();}
output_console(
&mut lock!(gui_api).output,
&mut gui_api.lock().unwrap().output,
&format!("XvB process can not completely continue, falling back to {}", XvbNode::P2pool),
ProcessName::Xvb
);
@ -629,9 +634,9 @@ async fn check_state_outcauses_xvb(
return true;
}
let is_xmrig_alive = lock!(process_xp).state == ProcessState::Alive
|| lock!(process_xmrig).state == ProcessState::Alive;
let is_p2pool_alive = lock!(process_p2pool).state == ProcessState::Alive;
let is_xmrig_alive = process_xp.lock().unwrap().state == ProcessState::Alive
|| process_xmrig.lock().unwrap().state == ProcessState::Alive;
let is_p2pool_alive = process_p2pool.lock().unwrap().state == ProcessState::Alive;
let p2pool_xmrig_alive = is_xmrig_alive && is_p2pool_alive;
// if state is middle because start is not finished yet, it will not do anything.
match state {
@ -643,25 +648,25 @@ async fn check_state_outcauses_xvb(
// request from public API must be executed at next loop, do not wait for 1 minute.
*first_loop = true;
output_console(
&mut lock!(gui_api).output,
&mut gui_api.lock().unwrap().output,
"XvB is now partially stopped because p2pool node or XMRig/XMRig-Proxy came offline.\nCheck P2pool and Xmrig/Xmrig-Proxy Tabs",
ProcessName::Xvb
);
output_console(
&mut lock!(gui_api).output,
&mut gui_api.lock().unwrap().output,
XVB_PUBLIC_ONLY,
ProcessName::Xvb,
);
lock!(process).state = ProcessState::Syncing;
process.lock().unwrap().state = ProcessState::Syncing;
}
ProcessState::Syncing if p2pool_xmrig_alive => {
info!("XvB | started this time with p2pool and xmrig");
// will put state on middle and update nodes
lock!(process).state = ProcessState::Alive;
process.lock().unwrap().state = ProcessState::Alive;
reset_data_xvb(pub_api, gui_api);
*first_loop = true;
output_console(
&mut lock!(gui_api).output,
&mut gui_api.lock().unwrap().output,
&[
"XvB is now started because p2pool and ",
msg_xmrig_or_proxy,
@ -699,7 +704,7 @@ fn signal_interrupt(
// check if STOP or RESTART Signal is given.
// if STOP, will put Signal to None, if Restart to Wait
// in either case, will break from loop.
let signal = lock!(process).signal;
let signal = process.lock().unwrap().signal;
match signal {
ProcessSignal::Stop => {
debug!("P2Pool Watchdog | Stop SIGNAL caught");
@ -712,13 +717,13 @@ fn signal_interrupt(
// insert the signal into output of XvB
// This is written directly into the GUI API, because sometimes the 900ms event loop can't catch it.
output_console(
&mut lock!(gui_api).output,
&mut gui_api.lock().unwrap().output,
"\n\n\nXvB stopped\n\n\n",
ProcessName::Xvb,
);
debug!("XvB Watchdog | Stop SIGNAL done, breaking");
lock!(process).signal = ProcessSignal::None;
lock!(process).state = ProcessState::Dead;
process.lock().unwrap().signal = ProcessSignal::None;
process.lock().unwrap().state = ProcessState::Dead;
// reset stats
reset_data_xvb(pub_api, gui_api);
return true;
@ -729,12 +734,12 @@ fn signal_interrupt(
info!("XvB Watchdog | Stopped ... Uptime was: [{}]", uptime);
// no output to console because service will be started with fresh output.
debug!("XvB Watchdog | Restart SIGNAL done, breaking");
lock!(process).state = ProcessState::Waiting;
process.lock().unwrap().state = ProcessState::Waiting;
reset_data_xvb(pub_api, gui_api);
return true;
}
ProcessSignal::UpdateNodes(node) => {
if lock!(process).state != ProcessState::Waiting {
if process.lock().unwrap().state != ProcessState::Waiting {
warn!("received the UpdateNode signal");
let token_xmrig = if xp_alive {
state_xp.token.clone()
@ -752,10 +757,10 @@ fn signal_interrupt(
// if both XvB nodes fail after checking, process will be partially stopped and a new spawn will verify if nodes are again online and so will continue the process completely if that's the case.
// if P2pool, the process has to stop the algo and continue partially. The process will continue completely if the confitions are met again.
// if XvB was not alive, then if it is for XvB nodes, it will check and update preferred node and set XMRig to P2pool if that's not the case.
let was_alive = lock!(process).state == ProcessState::Alive;
let was_alive = process.lock().unwrap().state == ProcessState::Alive;
// so it won't execute another signal of update nodes if it is already doing it.
lock!(process).state = ProcessState::Waiting;
lock!(process).signal = ProcessSignal::None;
process.lock().unwrap().state = ProcessState::Waiting;
process.lock().unwrap().signal = ProcessSignal::None;
spawn(
enc!((node, process, client, gui_api, pub_api, was_alive, address, token_xmrig, gui_api_xmrig, gui_api_xp,process_xrig) async move {
warn!("in spawn of UpdateNodes");
@ -764,11 +769,11 @@ fn signal_interrupt(
warn!("current is XvB node ? update to see which is available");
// a node is failing. We need to first verify if a node is available
XvbNode::update_fastest_node(&client, &gui_api, &pub_api, &process).await;
if lock!(process).state == ProcessState::OfflineNodesAll {
if process.lock().unwrap().state == ProcessState::OfflineNodesAll {
// No available nodes, so launch a process to verify periodically.
sleep(Duration::from_secs(10)).await;
warn!("node fail, set spawn that will retry nodes and update state.");
while lock!(process).state == ProcessState::OfflineNodesAll {
while process.lock().unwrap().state == ProcessState::OfflineNodesAll {
// this spawn will stay alive until nodes are joignable or XvB process is stopped or failed.
XvbNode::update_fastest_node(&client, &pub_api, &gui_api, &process).await;
sleep(Duration::from_secs(10)).await;
@ -780,12 +785,12 @@ fn signal_interrupt(
},
XvbNode::NorthAmerica|XvbNode::Europe if !was_alive => {
lock!(process).state = ProcessState::Syncing;
process.lock().unwrap().state = ProcessState::Syncing;
// Probably a start. We don't consider XMRig using XvB nodes without algo.
// can update xmrig and check status of state in the same time.
// Need to set XMRig to P2Pool if it wasn't. XMRig should have populated this value at his start.
// but if xmrig didn't start, don't update it.
if lock!(process_xrig).state == ProcessState::Alive && lock!(gui_api).current_node != Some(XvbNode::P2pool) {
if process_xrig.lock().unwrap().state == ProcessState::Alive && gui_api.lock().unwrap().current_node != Some(XvbNode::P2pool) {
spawn(enc!((client, token_xmrig, address, gui_api_xmrig, gui_api_xp, gui_api) async move{
let url_api = api_url_xmrig(xp_alive, true);
warn!("update xmrig to use node ?");
@ -804,7 +809,7 @@ fn signal_interrupt(
"XMRig"
};
output_console(
&mut lock!(gui_api).output,
&mut gui_api.lock().unwrap().output,
&format!(
"Failure to update {msg_xmrig_or_proxy} config with HTTP API.\nError: {}",
err
@ -813,9 +818,9 @@ fn signal_interrupt(
} else {
// update node xmrig
if xp_alive {
lock!(gui_api_xp).node = XvbNode::P2pool.to_string();
gui_api_xp.lock().unwrap().node = XvbNode::P2pool.to_string();
} else {
lock!(gui_api_xmrig).node = XvbNode::P2pool.to_string();
gui_api_xmrig.lock().unwrap().node = XvbNode::P2pool.to_string();
};
}
}
@ -832,20 +837,21 @@ fn signal_interrupt(
false
}
fn reset_data_xvb(pub_api: &Arc<Mutex<PubXvbApi>>, gui_api: &Arc<Mutex<PubXvbApi>>) {
let current_node = mem::take(&mut lock!(pub_api).current_node.clone());
let runtime_mode = mem::take(&mut lock!(gui_api).stats_priv.runtime_mode);
let runtime_manual_amount = mem::take(&mut lock!(gui_api).stats_priv.runtime_manual_amount);
let current_node = mem::take(&mut pub_api.lock().unwrap().current_node.clone());
let runtime_mode = mem::take(&mut gui_api.lock().unwrap().stats_priv.runtime_mode);
let runtime_manual_amount =
mem::take(&mut gui_api.lock().unwrap().stats_priv.runtime_manual_amount);
// let output = mem::take(&mut lock!(gui_api).output);
*lock!(pub_api) = PubXvbApi::new();
*lock!(gui_api) = PubXvbApi::new();
// let output = mem::take(&mut gui_api.lock().unwrap().output);
*pub_api.lock().unwrap() = PubXvbApi::new();
*gui_api.lock().unwrap() = PubXvbApi::new();
// to keep the value modified by xmrig even if xvb is dead.
lock!(pub_api).current_node = current_node;
pub_api.lock().unwrap().current_node = current_node;
// to not loose the information of runtime hero mode between restart
lock!(gui_api).stats_priv.runtime_mode = runtime_mode;
lock!(gui_api).stats_priv.runtime_manual_amount = runtime_manual_amount;
gui_api.lock().unwrap().stats_priv.runtime_mode = runtime_mode;
gui_api.lock().unwrap().stats_priv.runtime_manual_amount = runtime_manual_amount;
// message while starting must be preserved.
// lock!(pub_api).output = output;
// pub_api.lock().unwrap().output = output;
}
// print date time to console output in same format than xmrig
fn update_indicator_algo(
@ -856,14 +862,17 @@ fn update_indicator_algo(
time_donated: u32,
last_algorithm: &Arc<Mutex<Instant>>,
) {
if is_algo_started_once && !is_algo_finished && lock!(process).state == ProcessState::Alive {
let node = lock!(pub_api).current_node;
if is_algo_started_once
&& !is_algo_finished
&& process.lock().unwrap().state == ProcessState::Alive
{
let node = pub_api.lock().unwrap().current_node;
let msg_indicator = match node {
Some(XvbNode::P2pool) if time_donated > 0 => {
// algo is mining on p2pool but will switch to XvB after
// show time remaining on p2pool
lock!(pub_api).stats_priv.time_switch_node = XVB_TIME_ALGO
pub_api.lock().unwrap().stats_priv.time_switch_node = XVB_TIME_ALGO
.checked_sub(last_algorithm.lock().unwrap().elapsed().as_secs() as u32)
.unwrap_or_default()
.checked_sub(time_donated)
@ -874,17 +883,17 @@ fn update_indicator_algo(
// algo is mining on XvB or complelty mining on p2pool.
// show remaining time before next decision of algo
// because time of last algorithm could depass a little bit XVB_TIME_ALGO before next run, check the sub.
lock!(pub_api).stats_priv.time_switch_node = XVB_TIME_ALGO
pub_api.lock().unwrap().stats_priv.time_switch_node = XVB_TIME_ALGO
.checked_sub(last_algorithm.lock().unwrap().elapsed().as_secs() as u32)
.unwrap_or_default();
"time until next decision of algorithm".to_string()
}
};
lock!(pub_api).stats_priv.msg_indicator = msg_indicator;
pub_api.lock().unwrap().stats_priv.msg_indicator = msg_indicator;
} else {
// if algo is not running or process not alive
lock!(pub_api).stats_priv.time_switch_node = 0;
lock!(pub_api).stats_priv.msg_indicator = "Algorithm is not running".to_string();
pub_api.lock().unwrap().stats_priv.time_switch_node = 0;
pub_api.lock().unwrap().stats_priv.msg_indicator = "Algorithm is not running".to_string();
}
}
@ -912,16 +921,16 @@ fn current_controllable_hr(
gui_api_xmrig: &Arc<Mutex<PubXmrigApi>>,
) -> f32 {
if xp_alive {
if lock!(gui_api_xp).hashrate_10m > 0.0 {
lock!(gui_api_xp).hashrate_10m
if gui_api_xp.lock().unwrap().hashrate_10m > 0.0 {
gui_api_xp.lock().unwrap().hashrate_10m
} else {
lock!(gui_api_xp).hashrate_1m
gui_api_xp.lock().unwrap().hashrate_1m
}
} else if lock!(gui_api_xmrig).hashrate_raw_15m > 0.0 {
lock!(gui_api_xmrig).hashrate_raw_15m
} else if lock!(gui_api_xmrig).hashrate_raw_1m > 0.0 {
lock!(gui_api_xmrig).hashrate_raw_1m
} else if gui_api_xmrig.lock().unwrap().hashrate_raw_15m > 0.0 {
gui_api_xmrig.lock().unwrap().hashrate_raw_15m
} else if gui_api_xmrig.lock().unwrap().hashrate_raw_1m > 0.0 {
gui_api_xmrig.lock().unwrap().hashrate_raw_1m
} else {
lock!(gui_api_xmrig).hashrate_raw
gui_api_xmrig.lock().unwrap().hashrate_raw
}
}

View file

@ -11,7 +11,6 @@ use tokio::spawn;
use crate::{
components::node::{GetInfo, TIMEOUT_NODE_PING},
helper::{xvb::output_console, Process, ProcessName, ProcessState},
macros::lock,
GUPAX_VERSION_UNDERSCORE, XVB_NODE_EU, XVB_NODE_NA, XVB_NODE_PORT, XVB_NODE_RPC,
};
@ -112,16 +111,16 @@ impl XvbNode {
// if both nodes are dead, then the state of the process must be NodesOffline
info!("XvB node ping, all offline or ping failed, switching back to local p2pool",);
output_console(
&mut lock!(gui_api_xvb).output,
&mut gui_api_xvb.lock().unwrap().output,
"XvB node ping, all offline or ping failed, switching back to local p2pool",
ProcessName::Xvb,
);
lock!(process_xvb).state = ProcessState::OfflineNodesAll;
process_xvb.lock().unwrap().state = ProcessState::OfflineNodesAll;
} else {
// if node is up and because update_fastest is used only if token/address is valid, it means XvB process is Alive.
info!("XvB node ping, both online and best is {}", node.url());
output_console(
&mut lock!(gui_api_xvb).output,
&mut gui_api_xvb.lock().unwrap().output,
&format!("XvB node ping, {} is selected as the fastest.", node),
ProcessName::Xvb,
);
@ -129,13 +128,13 @@ impl XvbNode {
// could be used by xmrig who signal that a node is not joignable
// or by the start of xvb
// next iteration of the loop of XvB process will verify if all conditions are met to be alive.
if lock!(process_xvb).state != ProcessState::Syncing
&& lock!(process_xvb).state != ProcessState::Retry
if process_xvb.lock().unwrap().state != ProcessState::Syncing
&& process_xvb.lock().unwrap().state != ProcessState::Retry
{
lock!(process_xvb).state = ProcessState::Syncing;
process_xvb.lock().unwrap().state = ProcessState::Syncing;
}
}
lock!(pub_api_xvb).stats_priv.node = node;
pub_api_xvb.lock().unwrap().stats_priv.node = node;
}
async fn ping(ip: &str, client: &Client) -> u128 {
let request = client

View file

@ -12,7 +12,6 @@ use tokio::time::sleep;
use crate::{
disk::state::ManualDonationLevel,
helper::{xvb::output_console, Process, ProcessName, ProcessState},
macros::lock,
XVB_URL,
};
use crate::{
@ -122,7 +121,7 @@ impl XvbPrivStats {
match XvbPrivStats::request_api(client, address, token).await {
Ok(new_data) => {
debug!("XvB Watchdog | HTTP API request OK");
lock!(&pub_api).stats_priv = new_data;
pub_api.lock().unwrap().stats_priv = new_data;
// if last request failed, we are now ready to show stats again and maybe be alive next loop.
}
Err(err) => {
@ -131,17 +130,17 @@ impl XvbPrivStats {
XVB_URL, err
);
output_console(
&mut lock!(gui_api).output,
&mut gui_api.lock().unwrap().output,
&format!(
"Failure to retrieve private stats from {} because of this error: {}",
XVB_URL, err
),
ProcessName::Xvb,
);
lock!(process).state = ProcessState::Retry;
process.lock().unwrap().state = ProcessState::Retry;
// sleep here because it is in a spawn and will not block the user stopping or restarting the service.
output_console(
&mut lock!(gui_api).output,
&mut gui_api.lock().unwrap().output,
"Waiting 10 seconds before trying to get stats again.",
ProcessName::Xvb,
);

View file

@ -11,7 +11,6 @@ use tokio::time::sleep;
use crate::{
helper::{xvb::output_console, Process, ProcessName, ProcessState},
macros::lock,
XVB_URL_PUBLIC_API,
};
@ -64,12 +63,12 @@ impl XvbPubStats {
match XvbPubStats::request_api(client).await {
Ok(new_data) => {
debug!("XvB Watchdog | HTTP API request OK");
lock!(&pub_api).stats_pub = new_data;
pub_api.lock().unwrap().stats_pub = new_data;
// if last request failed, we are now ready to show stats again and maybe be alive next loop.
if lock!(process).state == ProcessState::Retry {
lock!(process).state = ProcessState::Syncing;
if process.lock().unwrap().state == ProcessState::Retry {
process.lock().unwrap().state = ProcessState::Syncing;
output_console(
&mut lock!(gui_api).output,
&mut gui_api.lock().unwrap().output,
"Stats are now working again after last successful request.",
ProcessName::Xvb,
);
@ -82,9 +81,9 @@ impl XvbPubStats {
);
// output the error to console
// if error already present, no need to print it multiple times.
if lock!(process).state != ProcessState::Retry {
if process.lock().unwrap().state != ProcessState::Retry {
output_console(
&mut lock!(gui_api).output,
&mut gui_api.lock().unwrap().output,
&format!(
"Failure to retrieve public stats from {}\nWill retry shortly...",
XVB_URL_PUBLIC_API
@ -93,10 +92,10 @@ impl XvbPubStats {
);
}
// we stop the algo (will be stopped by the check status on next loop) because we can't make the rest work without public stats. (winner in xvb private stats).
lock!(process).state = ProcessState::Retry;
process.lock().unwrap().state = ProcessState::Retry;
// sleep here because it is in a spawn and will not block the user stopping or restarting the service.
output_console(
&mut lock!(gui_api).output,
&mut gui_api.lock().unwrap().output,
"Waiting 10 seconds before trying to get stats again.",
ProcessName::Xvb,
);

View file

@ -4,7 +4,7 @@ use derive_more::Display;
use serde::Deserialize;
use crate::{
macros::lock, XVB_ROUND_DONOR_MEGA_MIN_HR, XVB_ROUND_DONOR_MIN_HR, XVB_ROUND_DONOR_VIP_MIN_HR,
XVB_ROUND_DONOR_MEGA_MIN_HR, XVB_ROUND_DONOR_MIN_HR, XVB_ROUND_DONOR_VIP_MIN_HR,
XVB_ROUND_DONOR_WHALE_MIN_HR, XVB_SIDE_MARGIN_1H,
};
@ -30,7 +30,7 @@ pub enum XvbRound {
pub(crate) fn round_type(share: u32, pub_api: &Arc<Mutex<PubXvbApi>>) -> Option<XvbRound> {
if share > 0 {
let stats_priv = &lock!(pub_api).stats_priv;
let stats_priv = &pub_api.lock().unwrap().stats_priv;
match (
((stats_priv.donor_1hr_avg * 1000.0) * XVB_SIDE_MARGIN_1H) as u32,
(stats_priv.donor_24hr_avg * 1000.0) as u32,

View file

@ -8,8 +8,8 @@ use crate::utils::regex::Regexes;
use std::io::Write;
//---------------------------------------------------------------------------------------------------- Init functions
use crate::app::App;
use crate::disk::state::*;
use crate::{components::node::Ping, miscs::clamp_scale};
use crate::{disk::state::*, utils::macros::lock};
use crate::{info, warn};
use eframe::NativeOptions;
use egui::TextStyle::Small;
@ -240,7 +240,7 @@ pub fn init_auto(app: &mut App) {
Arc::clone(&app.sudo),
);
} else {
lock!(app.sudo).signal = ProcessSignal::Start;
app.sudo.lock().unwrap().signal = ProcessSignal::Start;
app.error_state.ask_sudo(&app.sudo);
}
} else {

View file

@ -78,7 +78,7 @@ pub fn print_disk_file(path: &PathBuf) {
#[cold]
#[inline(never)]
pub fn print_gupax_p2pool_api(gupax_p2pool_api: &Arc<Mutex<GupaxP2poolApi>>) {
let api = lock!(gupax_p2pool_api);
let api = gupax_p2pool_api.lock().unwrap();
let log = match std::fs::read_to_string(&api.path_log) {
Ok(string) => string,
Err(e) => {
@ -130,7 +130,6 @@ pub fn cmp_f64(a: f64, b: f64) -> std::cmp::Ordering {
use crate::disk::gupax_p2pool_api::GupaxP2poolApi;
use crate::helper::ProcessName;
use crate::utils::macros::lock;
use chrono::Local;
use log::error;
use log::warn;

View file

@ -19,40 +19,10 @@
//
// | MACRO | PURPOSE | EQUIVALENT CODE |
// |---------|-----------------------------------------------|------------------------------------------------------------|
// | lock | Lock an [Arc<Mutex>] | a.lock().unwrap() |
// | lock2 | Lock a field inside a struct, both Arc<Mutex> | a.lock().unwrap().b.lock().unwrap() |
// | arc_mut | Create a new [Arc<Mutex>] | std::sync::Arc::new(std::sync::Mutex::new(my_value)) |
// | sleep | Sleep the current thread for x milliseconds | std::thread::sleep(std::time::Duration::from_millis(1000)) |
// | flip | Flip a bool in place | my_bool = !my_bool |
//
// Hopefully the long ass code on the right justifies usage of macros :D
//
// [lock2!()] works like this: "lock2!(my_first, my_second)"
// and expects it be a [Struct]-[field] relationship, e.g:
//
// let my_first = Arc::new(Mutex::new(Struct {
// my_second: Arc::new(Mutex::new(true)),
// }));
// lock2!(my_first, my_second);
//
// The equivalent code is: "my_first.lock().unwrap().my_second.lock().unwrap()" (see? this is long as hell)
// Locks and unwraps an [Arc<Mutex<T>]
macro_rules! lock {
($arc_mutex:expr) => {
$arc_mutex.lock().unwrap()
};
}
pub(crate) use lock;
// Locks and unwraps a field of a struct, both of them being [Arc<Mutex>]
// Yes, I know this is bad code.
macro_rules! lock2 {
($arc_mutex:expr, $arc_mutex_two:ident) => {
$arc_mutex.lock().unwrap().$arc_mutex_two.lock().unwrap()
};
}
pub(crate) use lock2;
// Creates a new [Arc<Mutex<T>]
macro_rules! arc_mut {
@ -83,31 +53,11 @@ pub(crate) use flip;
//---------------------------------------------------------------------------------------------------- TESTS
#[cfg(test)]
mod test {
#[test]
fn lock() {
use std::sync::{Arc, Mutex};
let arc_mutex = Arc::new(Mutex::new(false));
*lock!(arc_mutex) = true;
assert!(*lock!(arc_mutex));
}
#[test]
fn lock2() {
struct Ab {
a: Arc<Mutex<bool>>,
}
use std::sync::{Arc, Mutex};
let arc_mutex = Arc::new(Mutex::new(Ab {
a: Arc::new(Mutex::new(false)),
}));
*lock2!(arc_mutex, a) = true;
assert!(*lock2!(arc_mutex, a));
}
#[test]
fn arc_mut() {
let a = arc_mut!(false);
assert!(!(*lock!(a)));
assert!(!(*a.lock().unwrap()));
}
#[test]

View file

@ -23,7 +23,6 @@ use crate::{
constants::*,
disk::state::Xmrig,
helper::{Helper, ProcessSignal},
macros::*,
};
use log::*;
use std::{
@ -88,7 +87,7 @@ impl SudoState {
// Resets the state.
pub fn reset(state: &Arc<Mutex<Self>>) {
Self::wipe(state);
let mut state = lock!(state);
let mut state = state.lock().unwrap();
state.testing = false;
state.success = false;
// state.signal = ProcessSignal::None;
@ -101,7 +100,7 @@ impl SudoState {
pub fn wipe(state: &Arc<Mutex<Self>>) {
let mut new = String::with_capacity(256);
// new is now == old, and vice-versa.
std::mem::swap(&mut new, &mut lock!(state).pass);
std::mem::swap(&mut new, &mut state.lock().unwrap().pass);
// we're wiping & dropping the old pass here.
new.zeroize();
std::mem::drop(new);
@ -124,7 +123,7 @@ impl SudoState {
let path = path.to_path_buf();
thread::spawn(move || {
// Set to testing
lock!(state).testing = true;
state.lock().unwrap().testing = true;
// Make sure sudo timestamp is reset
let reset = Command::new("sudo")
@ -138,8 +137,8 @@ impl SudoState {
Err(e) => {
error!("Sudo | Couldn't reset timestamp: {}", e);
Self::wipe(&state);
lock!(state).msg = format!("Sudo error: {}", e);
lock!(state).testing = false;
state.lock().unwrap().msg = format!("Sudo error: {}", e);
state.lock().unwrap().testing = false;
return;
}
}
@ -155,7 +154,9 @@ impl SudoState {
// Write pass to STDIN
let mut stdin = sudo.stdin.take().unwrap();
stdin.write_all(lock!(state).pass.as_bytes()).unwrap();
stdin
.write_all(state.lock().unwrap().pass.as_bytes())
.unwrap();
drop(stdin);
// Sudo re-prompts and will hang.
@ -166,7 +167,7 @@ impl SudoState {
Ok(Some(code)) => {
if code.success() {
info!("Sudo | Password ... OK!");
lock!(state).success = true;
state.lock().unwrap().success = true;
break;
}
}
@ -177,8 +178,8 @@ impl SudoState {
Err(e) => {
error!("Sudo | Couldn't reset timestamp: {}", e);
Self::wipe(&state);
lock!(state).msg = format!("Sudo error: {}", e);
lock!(state).testing = false;
state.lock().unwrap().msg = format!("Sudo error: {}", e);
state.lock().unwrap().testing = false;
return;
}
}
@ -186,8 +187,8 @@ impl SudoState {
if let Err(e) = sudo.kill() {
warn!("Sudo | Kill error (it probably already exited): {}", e);
}
if lock!(state).success {
match lock!(state).signal {
if state.lock().unwrap().success {
match state.lock().unwrap().signal {
ProcessSignal::Restart => crate::helper::Helper::restart_xmrig(
&helper,
&xmrig,
@ -203,11 +204,11 @@ impl SudoState {
),
}
} else {
lock!(state).msg = "Incorrect password! (or sudo timeout)".to_string();
state.lock().unwrap().msg = "Incorrect password! (or sudo timeout)".to_string();
Self::wipe(&state);
}
lock!(state).signal = ProcessSignal::None;
lock!(state).testing = false;
state.lock().unwrap().signal = ProcessSignal::None;
state.lock().unwrap().testing = false;
});
}
}