Skip to content

Commit

Permalink
Add the 'mm2_stop' FFI function #961 (#962)
Browse files Browse the repository at this point in the history
* Add the 'mm2_stop' FFI function

* Remove unused StopErr::NoContext

* Change the 'StopErr::ErrorStopping' code from 3 to 2
  • Loading branch information
sergeyboyko0791 authored Jun 1, 2021
1 parent bd6bed0 commit a839d2f
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 11 deletions.
20 changes: 10 additions & 10 deletions mm2src/common/mm_ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,18 +180,18 @@ impl MmCtx {
big as u16
}

pub fn stop(&self) {
if self.stop.pin(true).is_ok() {
let mut stop_listeners = self.stop_listeners.lock().expect("Can't lock stop_listeners");
// NB: It is important that we `drain` the `stop_listeners` rather than simply iterating over them
// because otherwise there might be reference counting instances remaining in a listener
// that would prevent the contexts from properly `Drop`ping.
for mut listener in stop_listeners.drain(..) {
if let Err(err) = listener() {
log! ({"MmCtx::stop] Listener error: {}", err})
}
pub fn stop(&self) -> Result<(), String> {
try_s!(self.stop.pin(true));
let mut stop_listeners = self.stop_listeners.lock().expect("Can't lock stop_listeners");
// NB: It is important that we `drain` the `stop_listeners` rather than simply iterating over them
// because otherwise there might be reference counting instances remaining in a listener
// that would prevent the contexts from properly `Drop`ping.
for mut listener in stop_listeners.drain(..) {
if let Err(err) = listener() {
log! ({"MmCtx::stop] Listener error: {}", err})
}
}
Ok(())
}

/// True if the MarketMaker instance needs to stop.
Expand Down
43 changes: 43 additions & 0 deletions mm2src/mm2_lib/mm2_native_lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,3 +198,46 @@ pub extern "C" fn mm2_test(torch: i32, log_cb: extern "C" fn(line: *const c_char
log!("mm2_test] All done, passing the torch.");
torch
}

#[derive(Debug, PartialEq, Primitive)]
enum StopErr {
Ok = 0,
NotRunning = 1,
ErrorStopping = 2,
}

/// Stop an MM2 instance or reset the static variables.
#[no_mangle]
pub extern "C" fn mm2_stop() -> i8 {
// The log callback might be initialized already, so try to use the common logs.
use common::log::{error, warn};

if !LP_MAIN_RUNNING.load(Ordering::Relaxed) {
return StopErr::NotRunning as i8;
}

let ctx = CTX.load(Ordering::Relaxed);
if ctx == 0 {
warn!("mm2_stop] lp_main is running without ctx");
LP_MAIN_RUNNING.store(false, Ordering::Relaxed);
return StopErr::Ok as i8;
}

let ctx = match MmArc::from_ffi_handle(ctx) {
Ok(ctx) => ctx,
Err(_) => {
warn!("mm2_stop] lp_main is still running, although ctx has already been dropped");
LP_MAIN_RUNNING.store(false, Ordering::Relaxed);
// there is no need to rewrite the `CTX`, because it will be removed on `mm2_main`
return StopErr::Ok as i8;
},
};

match ctx.stop() {
Ok(()) => StopErr::Ok as i8,
Err(e) => {
error!("mm2_stop] {}", e);
StopErr::ErrorStopping as i8
},
}
}
5 changes: 4 additions & 1 deletion mm2src/rpc/lp_commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use bigdecimal::BigDecimal;
use coins::{disable_coin as disable_coin_impl, lp_coinfind, lp_coininit, MmCoinEnum};
use common::executor::{spawn, Timer};
use common::log::error;
use common::mm_ctx::MmArc;
use common::mm_metrics::MetricsOps;
use common::{rpc_err_response, rpc_response, HyRes};
Expand Down Expand Up @@ -194,7 +195,9 @@ pub fn stop(ctx: MmArc) -> HyRes {
// Stopping immediately leads to the "stop" RPC call failing with the "errno 10054" sometimes.
spawn(async move {
Timer::sleep(0.05).await;
ctx.stop();
if let Err(e) = ctx.stop() {
error!("Error stopping MmCtx: {}", e);
}
});
rpc_response(200, r#"{"result": "success"}"#)
}
Expand Down

0 comments on commit a839d2f

Please sign in to comment.