Add pointer to integer return value for all async functions

This commit is contained in:
Dietmar Maurer 2019-10-25 06:36:59 +02:00
parent 599499beaa
commit e44ea5eaad
4 changed files with 45 additions and 35 deletions

View File

@ -1,26 +1,38 @@
use failure::*; use failure::*;
use std::os::raw::{c_char, c_void}; use std::os::raw::{c_char, c_void, c_int};
use std::sync::{Mutex, Arc, mpsc::Sender }; use std::sync::{Mutex, Arc, mpsc::Sender };
use std::ffi::CString; use std::ffi::CString;
pub(crate) struct CallbackPointers { pub(crate) struct CallbackPointers {
pub callback: extern "C" fn(*mut c_void), pub callback: extern "C" fn(*mut c_void),
pub callback_data: *mut c_void, pub callback_data: *mut c_void,
pub error: * mut *mut c_char, pub result: *mut c_int,
pub error: *mut *mut c_char,
} }
unsafe impl std::marker::Send for CallbackPointers {} unsafe impl std::marker::Send for CallbackPointers {}
impl CallbackPointers { impl CallbackPointers {
pub fn send_result(self, result: Result<(), Error>) { pub fn send_result(self, result: Result<c_int, Error>) {
match result { match result {
Ok(_) => { Ok(ret) => {
unsafe { *(self.error) = std::ptr::null_mut(); } unsafe {
if self.result != std::ptr::null_mut() {
*(self.result) = ret;
}
}
(self.callback)(self.callback_data); (self.callback)(self.callback_data);
} }
Err(err) => { Err(err) => {
let errmsg = CString::new(format!("command error: {}", err)).unwrap(); let errmsg = CString::new(format!("command error: {}", err)).unwrap();
unsafe { *(self.error) = errmsg.into_raw(); } unsafe {
if self.result != std::ptr::null_mut() {
*(self.result) = -1;
}
if self.error != std::ptr::null_mut() {
*(self.error) = errmsg.into_raw();
}
}
(self.callback)(self.callback_data); (self.callback)(self.callback_data);
} }
} }

View File

@ -2,6 +2,7 @@ use failure::*;
use std::collections::HashSet; use std::collections::HashSet;
use std::sync::{Mutex, Arc}; use std::sync::{Mutex, Arc};
use std::ptr; use std::ptr;
use std::os::raw::c_int;
use futures::future::{Future, TryFutureExt}; use futures::future::{Future, TryFutureExt};
use serde_json::{json, Value}; use serde_json::{json, Value};
@ -177,7 +178,7 @@ pub(crate) async fn close_image(
client: Arc<BackupWriter>, client: Arc<BackupWriter>,
registry: Arc<Mutex<ImageRegistry>>, registry: Arc<Mutex<ImageRegistry>>,
dev_id: u8, dev_id: u8,
) -> Result<(), Error> { ) -> Result<c_int, Error> {
println!("close image {}", dev_id); println!("close image {}", dev_id);
@ -216,7 +217,7 @@ pub(crate) async fn close_image(
"csum": proxmox::tools::digest_to_hex(&upload_result.csum), "csum": proxmox::tools::digest_to_hex(&upload_result.csum),
})); }));
Ok(()) Ok(0)
} }
pub(crate) async fn write_data( pub(crate) async fn write_data(
@ -229,7 +230,7 @@ pub(crate) async fn write_data(
offset: u64, offset: u64,
size: u64, // actual data size size: u64, // actual data size
chunk_size: u64, // expected data size chunk_size: u64, // expected data size
) -> Result<(), Error> { ) -> Result<c_int, Error> {
println!("dev {}: write {} {}", dev_id, offset, size); println!("dev {}: write {} {}", dev_id, offset, size);
@ -346,7 +347,7 @@ pub(crate) async fn write_data(
println!("upload chunk sucessful"); println!("upload chunk sucessful");
Ok(()) Ok(size as c_int)
} }
pub(crate) async fn finish_backup( pub(crate) async fn finish_backup(
@ -354,7 +355,7 @@ pub(crate) async fn finish_backup(
crypt_config: Option<Arc<CryptConfig>>, crypt_config: Option<Arc<CryptConfig>>,
registry: Arc<Mutex<ImageRegistry>>, registry: Arc<Mutex<ImageRegistry>>,
setup: BackupSetup, setup: BackupSetup,
) -> Result<(), Error> { ) -> Result<c_int, Error> {
println!("call finish"); println!("call finish");
@ -378,5 +379,5 @@ pub(crate) async fn finish_backup(
client.finish().await?; client.finish().await?;
Ok(()) Ok(0)
} }

View File

@ -51,7 +51,7 @@ macro_rules! raise_error_int {
}} }}
} }
/// Create new instance /// Create a new instance
#[no_mangle] #[no_mangle]
pub extern "C" fn proxmox_backup_new( pub extern "C" fn proxmox_backup_new(
repo: *const c_char, repo: *const c_char,
@ -119,19 +119,20 @@ pub extern "C" fn proxmox_backup_connect_async(
handle: *mut ProxmoxBackupHandle, handle: *mut ProxmoxBackupHandle,
callback: extern "C" fn(*mut c_void), callback: extern "C" fn(*mut c_void),
callback_data: *mut c_void, callback_data: *mut c_void,
error: * mut * mut c_char, result: *mut c_int,
error: *mut *mut c_char,
) { ) {
let task = unsafe { &mut *(handle as * mut BackupTask) }; let task = unsafe { &mut *(handle as * mut BackupTask) };
if let Some(_reason) = &task.aborted { if let Some(_reason) = &task.aborted {
let errmsg = CString::new("task already aborted".to_string()).unwrap(); let errmsg = CString::new("task already aborted".to_string()).unwrap();
unsafe { *error = errmsg.into_raw(); } unsafe { *result = -1; *error = errmsg.into_raw(); }
callback(callback_data); callback(callback_data);
return; return;
} }
let msg = BackupMessage::Connect { let msg = BackupMessage::Connect {
callback_info: CallbackPointers { callback, callback_data, error }, callback_info: CallbackPointers { callback, callback_data, error, result },
}; };
println!("connect_async start"); println!("connect_async start");
@ -252,14 +253,14 @@ pub extern "C" fn proxmox_backup_write_data_async(
size: u64, size: u64,
callback: extern "C" fn(*mut c_void), callback: extern "C" fn(*mut c_void),
callback_data: *mut c_void, callback_data: *mut c_void,
result: *mut c_int,
error: * mut * mut c_char, error: * mut * mut c_char,
) { ) {
let task = unsafe { &mut *(handle as * mut BackupTask) }; let task = unsafe { &mut *(handle as * mut BackupTask) };
let callback_info = CallbackPointers { callback, callback_data, error, result };
if let Some(_reason) = &task.aborted { if let Some(_reason) = &task.aborted {
let errmsg = CString::new("task already aborted".to_string()).unwrap(); callback_info.send_result(Err(format_err!("task already aborted")));
unsafe { *error = errmsg.into_raw(); }
callback(callback_data);
return; return;
} }
@ -268,7 +269,7 @@ pub extern "C" fn proxmox_backup_write_data_async(
data: DataPointer(data), data: DataPointer(data),
offset, offset,
size, size,
callback_info: CallbackPointers { callback, callback_data, error }, callback_info,
}; };
println!("write_data_async start"); println!("write_data_async start");
@ -285,21 +286,18 @@ pub extern "C" fn proxmox_backup_close_image_async(
dev_id: u8, dev_id: u8,
callback: extern "C" fn(*mut c_void), callback: extern "C" fn(*mut c_void),
callback_data: *mut c_void, callback_data: *mut c_void,
result: *mut c_int,
error: * mut * mut c_char, error: * mut * mut c_char,
) { ) {
let task = unsafe { &mut *(handle as * mut BackupTask) }; let task = unsafe { &mut *(handle as * mut BackupTask) };
let callback_info = CallbackPointers { callback, callback_data, error, result };
if let Some(_reason) = &task.aborted { if let Some(_reason) = &task.aborted {
let errmsg = CString::new("task already aborted".to_string()).unwrap(); callback_info.send_result(Err(format_err!("task already aborted")));
unsafe { *error = errmsg.into_raw(); }
callback(callback_data);
return; return;
} }
let msg = BackupMessage::CloseImage { let msg = BackupMessage::CloseImage { dev_id, callback_info };
dev_id,
callback_info: CallbackPointers { callback, callback_data, error },
};
println!("close_image_async start"); println!("close_image_async start");
let _res = task.command_tx.send(msg); // fixme: log errors let _res = task.command_tx.send(msg); // fixme: log errors
@ -315,20 +313,18 @@ pub extern "C" fn proxmox_backup_finish_async(
handle: *mut ProxmoxBackupHandle, handle: *mut ProxmoxBackupHandle,
callback: extern "C" fn(*mut c_void), callback: extern "C" fn(*mut c_void),
callback_data: *mut c_void, callback_data: *mut c_void,
result: *mut c_int,
error: * mut * mut c_char, error: * mut * mut c_char,
) { ) {
let task = unsafe { &mut *(handle as * mut BackupTask) }; let task = unsafe { &mut *(handle as * mut BackupTask) };
let callback_info = CallbackPointers { callback, callback_data, error, result };
if let Some(_reason) = &task.aborted { if let Some(_reason) = &task.aborted {
let errmsg = CString::new("task already aborted".to_string()).unwrap(); callback_info.send_result(Err(format_err!("task already aborted")));
unsafe { *error = errmsg.into_raw(); }
callback(callback_data);
return; return;
} }
let msg = BackupMessage::Finish { let msg = BackupMessage::Finish { callback_info };
callback_info: CallbackPointers { callback, callback_data, error },
};
println!("finish_async start"); println!("finish_async start");
let _res = task.command_tx.send(msg); // fixme: log errors let _res = task.command_tx.send(msg); // fixme: log errors

View File

@ -4,6 +4,7 @@ use std::thread::JoinHandle;
use std::sync::{Mutex, Arc}; use std::sync::{Mutex, Arc};
use std::sync::atomic::{AtomicU64, Ordering}; use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::mpsc::{channel, Sender, Receiver}; use std::sync::mpsc::{channel, Sender, Receiver};
use std::os::raw::c_int;
use futures::future::{Future, Either, FutureExt}; use futures::future::{Future, Either, FutureExt};
@ -59,7 +60,7 @@ impl BackupTask {
} }
} }
fn handle_async_command<F: 'static + Send + Future<Output=Result<(), Error>>>( fn handle_async_command<F: 'static + Send + Future<Output=Result<c_int, Error>>>(
command_future: F, command_future: F,
abort_future: impl 'static + Send + Future<Output=Result<(), Error>>, abort_future: impl 'static + Send + Future<Output=Result<(), Error>>,
callback_info: CallbackPointers, callback_info: CallbackPointers,
@ -132,7 +133,7 @@ fn backup_worker_task(
BackupMessage::Connect { callback_info } => { BackupMessage::Connect { callback_info } => {
client = match setup.connect().await { client = match setup.connect().await {
Ok(client) => { Ok(client) => {
callback_info.send_result(Ok(())); callback_info.send_result(Ok(0));
Some(client) Some(client)
} }
Err(err) => { Err(err) => {