#![allow(unused_imports)]
#![allow(dead_code)]
#![allow(unused_variables)]
extern crate core;
use std::sync::Arc;
use std::ptr;
use std::rt::heap::allocate;
use std::rt::heap::deallocate;
use std::mem::size_of;
use std::sync::Mutex;
use std::intrinsics::copy_memory;
use std::intrinsics::transmute;
use std::io::timer::sleep;
use std::time::duration::Duration;
use time::get_time;
use time::Timespec;
use rawmessage::RawMessage;
use endpoint::Endpoint;
use message::Message;
use message::MessagePayload;
use tcp;
use tcp::TcpBridgeListener;
use tcp::TcpBridgeConnector;
pub type ID = u64;
pub const UNUSED_ID: ID = !0u64;
struct Internal {
endpoints: Vec<Endpoint>,
hueid: u64, sid: u64,
}
pub struct Net {
i: Arc<Mutex<Internal>>,
}
impl Clone for Net {
fn clone(&self) -> Net {
Net {
i: self.i.clone(),
}
}
}
const NET_MAXLATENCY: i64 = 100000; const NET_MINLATENCY: i64 = 100;
impl Net {
fn sleeperthread(net: Net) {
let mut latency: i64 = NET_MAXLATENCY;
let mut wokesomeone: bool;
loop {
sleep(Duration::microseconds(latency));
let ctime: Timespec = get_time();
{
let mut i = net.i.lock();
wokesomeone = false;
for ep in i.endpoints.iter_mut() {
if ctime > ep.getwaketime() {
if ep.wakeonewaiter() {
wokesomeone = true;
}
}
}
}
if wokesomeone {
latency = latency / 2;
if latency < NET_MINLATENCY {
latency = NET_MINLATENCY;
}
} else {
latency = latency * 2;
if latency > NET_MAXLATENCY {
latency = NET_MAXLATENCY;
}
}
}
}
pub fn new(sid: u64) -> Net {
let net = Net {
i: Arc::new(Mutex::new(Internal {
endpoints: Vec::new(),
hueid: 0x10000,
sid: sid,
})),
};
let netclone = net.clone();
spawn(move || { Net::sleeperthread(netclone) });
net
}
pub fn tcplisten(&self, addr: String) -> TcpBridgeListener {
tcp::listener::TcpBridgeListener::new(self, addr)
}
pub fn tcpconnect(&self, addr: String) -> TcpBridgeConnector {
tcp::connector::_TcpBridgeConnector::new(self, addr)
}
pub fn sendas(&self, rawmsg: &Message, frmsid: u64, frmeid: u64) {
let mut duped = rawmsg.dup();
duped.srcsid = frmsid;
duped.srceid = frmeid;
self.send_internal(&duped);
}
pub fn send(&self, msg: &Message) {
match msg.payload {
MessagePayload::Sync(ref payload) => {
panic!("use `sendsync` instead of `send` for sync messages");
}
_ => {
}
}
let duped = msg.dup();
self.send_internal(&duped);
}
pub fn sendcloneas(&self, msg: &mut Message, fromsid: u64, fromeid: u64) {
if !msg.is_clone() {
panic!("`sendclone` can only be used with clone messages!")
}
msg.srcsid = fromsid;
msg.srceid = fromeid;
self.sendclone(msg);
}
pub fn sendclone(&self, msg: &Message) {
let mut i = self.i.lock();
if msg.dstsid != 1 && msg.dstsid != i.sid {
panic!("you can only send clone message to local net!")
}
for ep in i.endpoints.iter_mut() {
if msg.dsteid == ep.geteid() {
ep.give(msg);
}
}
}
pub fn sendsyncas(&self, mut msg: Message, frmsid: u64, frmeid: u64) {
msg.srcsid = frmsid;
msg.srceid = frmeid;
self.sendsync(msg);
}
pub fn sendsync(&self, msg: Message) {
let mut i = self.i.lock();
if msg.dstsid != 1 && msg.dstsid != i.sid {
panic!("you can only send sync message to local net!")
}
if msg.dsteid == 0 {
panic!("you can only send sync message to a single endpoint!");
}
for ep in i.endpoints.iter_mut() {
if msg.dsteid == ep.geteid() {
ep.givesync(msg);
return;
}
}
}
fn send_internal(&self, rawmsg: &Message) {
match rawmsg.dstsid {
0 => {
let mut i = self.i.lock();
for ep in i.endpoints.iter_mut() {
if rawmsg.dsteid == 0 || rawmsg.dsteid == ep.geteid() {
ep.give(rawmsg);
}
}
},
1 => {
let mut i = self.i.lock();
let sid = i.sid;
for ep in i.endpoints.iter_mut() {
if ep.getsid() == sid {
if rawmsg.dsteid == 0 || rawmsg.dsteid == ep.geteid() {
ep.give(rawmsg);
}
}
}
},
dstsid => {
let mut i = self.i.lock();
for ep in i.endpoints.iter_mut() {
println!("trying to send {} to {}", dstsid, ep.getsid());
if ep.getsid() == dstsid {
if rawmsg.dsteid == 0 || rawmsg.dsteid == ep.geteid() {
ep.give(rawmsg);
}
}
}
}
}
}
pub fn get_neweid(&mut self) -> u64 {
let mut i = self.i.lock();
let eid = i.hueid;
i.hueid += 1;
eid
}
pub fn new_endpoint_withid(&mut self, eid: u64) -> Endpoint {
let mut i = self.i.lock();
if eid > i.hueid {
i.hueid = eid + 1;
}
let ep = Endpoint::new(i.sid, eid, self.clone());
i.endpoints.push(ep.clone());
ep
}
pub fn add_endpoint(&mut self, ep: Endpoint) {
self.i.lock().endpoints.push(ep);
}
pub fn new_endpoint(&mut self) -> Endpoint {
let mut i = self.i.lock();
let ep = Endpoint::new(i.sid, i.hueid, self.clone());
i.hueid += 1;
let epclone = ep.clone();
i.endpoints.push(epclone);
ep
}
pub fn getserveraddr(&self) -> u64 {
self.i.lock().sid
}
}