#![allow(unused_imports)]
#![allow(dead_code)]
#![allow(unused_variables)]
extern crate core;
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 tcp::TCPLISTENER;
use tcp::TCPListener;
use tcp::TCPCONNECTOR;
use tcp::TCPConnector;
pub enum NetProtocolAddress {
TCP(String, u16)
}
struct Internal {
lock: Mutex<uint>,
endpoints: Vec<Endpoint>,
refcnt: uint,
hueid: u64, }
pub struct Net {
i: *mut Internal,
sid: u64, }
impl Drop for Net {
fn drop(&mut self) {
unsafe {
let locked = (*self.i).lock.lock();
if (*self.i).refcnt == 0 {
panic!("drop called with refcnt zero");
}
(*self.i).refcnt -= 1;
if (*self.i).refcnt == 0 {
deallocate(self.i as *mut u8, size_of::<Internal>(), size_of::<uint>());
}
}
}
}
impl Clone for Net {
fn clone(&self) -> Net {
unsafe {
let locked = (*self.i).lock.lock();
(*self.i).refcnt += 1;
Net {
i: self.i,
sid: self.sid,
}
}
}
}
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 lock = unsafe { (*net.i).lock.lock() };
wokesomeone = false;
for ep in unsafe { (*net.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 i: *mut Internal;
unsafe {
i = allocate(size_of::<Internal>(), size_of::<uint>()) as *mut Internal;
(*i).lock = Mutex::new(0);
(*i).endpoints = Vec::new();
(*i).refcnt = 1;
(*i).hueid = 0x10000;
}
let net = Net {
i: i,
sid: sid,
};
let netclone = net.clone();
spawn(move || { Net::sleeperthread(netclone) });
net
}
unsafe fn clone_nolock(&self) -> Net {
(*self.i).refcnt += 1;
Net {
i: self.i,
sid: self.sid,
}
}
pub fn tcplisten(&self, host: String, port: u16) -> TCPLISTENER {
TCPListener::new(self, host, port)
}
pub fn tcpconnect(&self, host: String, port: u16) -> TCPCONNECTOR {
TCPConnector::new(self, host, port)
}
pub fn sendas(&self, rawmsg: &RawMessage, frmsid: u64, frmeid: u64) {
let mut duped = rawmsg.dup();
duped.srcsid = frmsid;
duped.srceid = frmeid;
self.send_internal(&duped);
}
pub fn send(&self, rawmsg: &RawMessage) {
let duped = rawmsg.dup();
self.send_internal(&duped);
}
fn send_internal(&self, rawmsg: &RawMessage) {
match rawmsg.dstsid {
0 => {
unsafe {
let lock = (*self.i).lock.lock();
for ep in (*self.i).endpoints.iter_mut() {
if rawmsg.dsteid == 0 || rawmsg.dsteid == ep.eid {
ep.give(rawmsg);
}
}
}
},
1 => {
unsafe {
let lock = (*self.i).lock.lock();
for ep in (*self.i).endpoints.iter_mut() {
if ep.sid == self.sid {
if rawmsg.dsteid == 0 || rawmsg.dsteid == ep.eid {
ep.give(rawmsg);
}
}
}
}
},
dstsid => {
unsafe {
let lock = (*self.i).lock.lock();
for ep in (*self.i).endpoints.iter_mut() {
if ep.sid == dstsid {
if rawmsg.dsteid == 0 || rawmsg.dsteid == ep.eid {
ep.give(rawmsg);
}
}
}
}
}
}
}
pub fn new_endpoint_withid(&mut self, eid: u64) -> Endpoint {
unsafe {
let lock = (*self.i).lock.lock();
if eid > (*self.i).hueid {
(*self.i).hueid = eid + 1;
}
let ep = Endpoint::new(self.sid, eid, self.clone_nolock());
(*self.i).endpoints.push(ep.clone());
ep
}
}
pub fn new_endpoint(&mut self) -> Endpoint {
unsafe {
let ep: Endpoint;
{
let lock = (*self.i).lock.lock();
ep = Endpoint::new(self.sid, (*self.i).hueid, self.clone_nolock());
(*self.i).hueid += 1;
}
let epcloned = ep.clone();
{
let lock = (*self.i).lock.lock();
(*self.i).endpoints.push(epcloned);
}
ep
}
}
pub fn getserveraddr(&self) -> u64 {
self.sid
}
}