use std::ops::Deref;
use std::slice;
use std::mem::ManuallyDrop;
use std::ptr;
use libc::*;
#[repr(C)]
pub struct NetworkBuffer {
delete: unsafe extern "C" fn(data: *mut u8, len: c_ulong, capacity: c_ulong),
data: *mut u8,
len: c_ulong,
capacity: c_ulong
}
impl Drop for NetworkBuffer {
fn drop(&mut self) {
unsafe {
(self.delete)(self.data, self.len, self.capacity);
}
}
}
impl Deref for NetworkBuffer {
type Target = [u8];
fn deref(&self) -> &Self::Target {
self.as_slice()
}
}
impl NetworkBuffer {
pub fn empty() -> Self {
Self {
delete: delete_empty_network_buffer,
data: ptr::null_mut(),
len: 0,
capacity: 0
}
}
pub fn new(vec: Vec<u8>) -> Self {
let mut vec = ManuallyDrop::new(vec);
Self {
delete: delete_vector_network_buffer,
data: vec.as_mut_ptr(),
len: vec.len() as c_ulong,
capacity: vec.capacity() as c_ulong
}
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
if self.len > 0 {
slice::from_raw_parts(self.data, self.len as usize)
} else {
&[]
}
}
}
}
unsafe extern "C" fn delete_empty_network_buffer(_data: *mut u8, _len: c_ulong, _capacity: c_ulong) {}
unsafe extern "C" fn delete_vector_network_buffer(data: *mut u8, len: c_ulong, capacity: c_ulong) {
let _: Vec<u8> = Vec::from_raw_parts(data, len as usize, capacity as usize);
}
pub type NetworkTraitObject = *mut c_void;
#[repr(C)]
pub struct NetworkSupport {
pub delete: unsafe extern "C" fn(obj: *mut NetworkTraitObject),
pub rank: unsafe extern "C" fn(obj: *const NetworkTraitObject) -> c_int,
pub size: unsafe extern "C" fn(obj: *const NetworkTraitObject) -> c_int,
pub send: unsafe extern "C" fn(obj: *mut NetworkTraitObject, pid: c_int, msg: *const u8, count: c_ulong),
pub send_async: unsafe extern "C" fn(obj: *mut NetworkTraitObject, pid: c_int, msg: NetworkBuffer),
pub try_recv: unsafe extern "C" fn(obj: *mut NetworkTraitObject, pid: *mut c_int, result: *mut c_int) -> NetworkBuffer,
pub recv: unsafe extern "C" fn(obj: *mut NetworkTraitObject, pid: *mut c_int, result: *mut c_int) -> NetworkBuffer,
pub test: unsafe extern "C" fn(obj: *mut NetworkTraitObject),
pub wait: unsafe extern "C" fn(obj: *mut NetworkTraitObject),
pub request_count: unsafe extern "C" fn(obj: *const NetworkTraitObject) -> c_ulong,
pub abort: unsafe extern "C" fn(obj: *mut NetworkTraitObject, code: i32),
pub barrier: unsafe extern "C" fn(obj: *mut NetworkTraitObject),
pub trait_object: NetworkTraitObject
}
impl Drop for NetworkSupport {
fn drop(&mut self) {
unsafe {
(self.delete)(&mut self.trait_object);
}
}
}
impl NetworkSupport {
pub fn rank(&self) -> c_int {
unsafe {
(self.rank)(&self.trait_object)
}
}
pub fn size(&self) -> c_int {
unsafe {
(self.size)(&self.trait_object)
}
}
pub fn send(&mut self, pid: c_int, msg: &[u8]) {
unsafe {
(self.send)(&mut self.trait_object, pid, msg.as_ptr(), msg.len() as c_ulong)
}
}
pub fn send_async(&mut self, pid: c_int, msg: NetworkBuffer) {
unsafe {
(self.send_async)(&mut self.trait_object, pid, msg)
}
}
pub fn try_recv(&mut self) -> Result<Option<(NetworkBuffer, c_int)>, c_int> {
unsafe {
let mut pid = 0 as c_int;
let mut result = 0 as c_int;
let buf = (self.try_recv)(&mut self.trait_object, &mut pid, &mut result);
if result == 0 {
Result::Ok(None)
} else if result > 0 {
Result::Ok(Some((buf, pid)))
} else {
Result::Err(pid)
}
}
}
pub fn recv(&mut self) -> Result<(NetworkBuffer, c_int), c_int> {
unsafe {
let mut pid = 0 as c_int;
let mut result = 0 as c_int;
let buf = (self.recv)(&mut self.trait_object, &mut pid, &mut result);
if result > 0 {
Result::Ok((buf, pid))
} else {
Result::Err(pid)
}
}
}
pub fn test(&mut self) {
unsafe {
(self.test)(&mut self.trait_object)
}
}
pub fn wait(&mut self) {
unsafe {
(self.wait)(&mut self.trait_object)
}
}
pub fn request_count(&self) -> usize {
unsafe {
(self.request_count)(&self.trait_object) as usize
}
}
pub fn abort(&mut self, code: i32) {
unsafe {
(self.abort)(&mut self.trait_object, code)
}
}
pub fn barrier(&mut self) {
unsafe {
(self.barrier)(&mut self.trait_object)
}
}
}