#![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: ID, sid: ID,
}
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 getepcount(&self) -> uint {
self.i.lock().endpoints.len()
}
pub fn new(sid: ID) -> 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: ID, frmeid: ID) -> uint {
let mut duped = rawmsg.dup();
duped.srcsid = frmsid;
duped.srceid = frmeid;
self.send_internal(&duped)
}
pub fn send(&self, msg: &Message) -> uint {
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: ID, fromeid: ID) -> uint {
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) -> uint {
let mut i = self.i.lock();
let mut ocnt = 0u;
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() {
if ep.give(msg) {
ocnt += 1;
}
}
}
ocnt
}
pub fn sendsyncas(&self, mut msg: Message, frmsid: ID, frmeid: ID) -> uint {
msg.srcsid = frmsid;
msg.srceid = frmeid;
self.sendsync(msg)
}
pub fn sendsync(&self, msg: Message) -> uint {
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() {
if ep.givesync(msg) {
return 1;
}
return 0;
}
}
0
}
fn send_internal(&self, msg: &Message) -> uint {
let mut ocnt = 0u;
match msg.dstsid {
0 => {
let mut i = self.i.lock();
for ep in i.endpoints.iter_mut() {
if !msg.canloop && msg.srceid == ep.geteid() && msg.srcsid == ep.getsid() {
continue;
}
if msg.dsteid == 0 || msg.dsteid == ep.geteid() {
if ep.give(msg) {
ocnt += 1;
}
}
}
ocnt
},
1 => {
let mut i = self.i.lock();
let sid = i.sid;
for ep in i.endpoints.iter_mut() {
if !msg.canloop && msg.srceid == ep.geteid() && msg.srcsid == ep.getsid() {
continue;
}
if ep.getsid() == sid {
if msg.dsteid == 0 || msg.dsteid == ep.geteid() {
if ep.give(msg) {
ocnt += 1;
}
}
}
}
ocnt
},
dstsid => {
let mut i = self.i.lock();
for ep in i.endpoints.iter_mut() {
if !msg.canloop && msg.srceid == ep.geteid() && msg.srcsid == ep.getsid() {
continue;
}
if ep.getsid() == dstsid {
if msg.dsteid == 0 || msg.dsteid == ep.geteid() {
if ep.give(msg) {
ocnt += 1;
}
}
}
}
ocnt
}
}
}
pub fn get_neweid(&mut self) -> ID {
let mut i = self.i.lock();
let eid = i.hueid;
i.hueid += 1;
eid
}
pub fn new_endpoint_withid(&mut self, eid: ID) -> 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) -> ID {
self.i.lock().sid
}
}