use nix::sys::socket::Backlog;
use std::time::Duration;
use rtipc::ChannelGroup;
use rtipc::Consumer;
use rtipc::PopResult;
use rtipc::Producer;
use rtipc::TryPushResult;
use rtipc::Server;
use crate::common::CommandId;
use crate::common::MsgCommand;
use crate::common::MsgEvent;
use crate::common::MsgResponse;
use crate::common::wait_pollin;
mod common;
struct App {
command: Consumer<MsgCommand>,
response: Producer<MsgResponse>,
event: Producer<MsgEvent>,
}
fn print_group(grp: &ChannelGroup) {
let attr = grp.get_attr();
let grp_info = str::from_utf8(attr.info.iter().as_slice()).unwrap();
let cmd_info = str::from_utf8(&attr.consumers.get(0).unwrap().info).unwrap();
let rsp_info = str::from_utf8(&attr.producers.get(0).unwrap().info).unwrap();
let evt_info = str::from_utf8(&attr.producers.get(1).unwrap().info).unwrap();
println!(
"server received request grp={} cmd={} rsp={} evt={}",
grp_info, cmd_info, rsp_info, evt_info
);
}
impl App {
pub fn new(mut grp: ChannelGroup) -> Self {
print_group(&grp);
let command = grp.acquire_consumer(0).unwrap();
let response = grp.acquire_producer(0).unwrap();
let event = grp.acquire_producer(1).unwrap();
Self {
command,
response,
event,
}
}
fn run(&mut self) {
let mut run = true;
let mut cnt = 0;
while run {
let eventfd = self.command.eventfd().unwrap();
let _ = wait_pollin(eventfd, Duration::from_millis(10));
match self.command.pop().unwrap() {
PopResult::NoMessage => continue,
PopResult::NoNewMessage => continue,
PopResult::Success => {}
PopResult::SuccessMessagesDiscarded => {}
};
let cmd = self.command.current_message().unwrap();
self.response.current_message().id = cmd.id;
println!("server received command: id = {}", cmd.id);
let cmdid: CommandId = unsafe { ::std::mem::transmute(cmd.id) };
self.response.current_message().result = match cmdid {
CommandId::Hello => 0,
CommandId::Stop => {
run = false;
0
}
CommandId::SendEvent => self.send_events(
unsafe { cmd.args.send.id },
unsafe { cmd.args.send.num },
unsafe { cmd.args.send.force },
),
CommandId::Div => {
let (err, res) = self.div(unsafe { cmd.args.div.divident }, unsafe {
cmd.args.div.divisor
});
self.response.current_message().data.quotient = res;
err
}
};
self.response.force_push().unwrap();
cnt += 1;
}
}
fn send_events(&mut self, id: u32, num: u32, force: bool) -> i32 {
for i in 0..num {
let event = self.event.current_message();
event.id = id;
event.nr = i;
if force {
self.event.force_push().unwrap();
} else {
if self.event.try_push().unwrap() == TryPushResult::QueueFull {
return i as i32;
}
}
}
num as i32
}
fn div(&mut self, a: f64, b: f64) -> (i32, f64) {
if b == 0.0 { (-1, 0.0) } else { (0, a / b) }
}
}
fn main() {
let backlog = Backlog::new(1).unwrap();
let server = Server::new("rtipc.sock", backlog).unwrap();
let grp = server.conditional_accept(|_| true).unwrap();
let mut app = App::new(grp);
app.run();
}