libstd: Fix merge fallout.
This commit is contained in:
parent
ee52865c88
commit
18df18c817
src
librustc
metadata
middle
libstd/rt
libsyntax
@ -54,18 +54,6 @@ pub fn each_lang_item(cstore: @mut cstore::CStore,
|
||||
}
|
||||
|
||||
/// Iterates over all the paths in the given crate.
|
||||
#[cfg(stage0)]
|
||||
pub fn each_path(cstore: @mut cstore::CStore,
|
||||
cnum: ast::crate_num,
|
||||
f: &fn(&str, decoder::def_like, ast::visibility) -> bool) {
|
||||
let crate_data = cstore::get_crate_data(cstore, cnum);
|
||||
let get_crate_data: decoder::GetCrateDataCb = |cnum| {
|
||||
cstore::get_crate_data(cstore, cnum)
|
||||
};
|
||||
decoder::each_path(cstore.intr, crate_data, get_crate_data, f)
|
||||
}
|
||||
/// Iterates over all the paths in the given crate.
|
||||
#[cfg(not(stage0))]
|
||||
pub fn each_path(cstore: @mut cstore::CStore,
|
||||
cnum: ast::crate_num,
|
||||
f: &fn(&str, decoder::def_like, ast::visibility) -> bool)
|
||||
|
@ -566,14 +566,6 @@ pub fn _each_path(intr: @ident_interner,
|
||||
return broken;
|
||||
}
|
||||
|
||||
#[cfg(stage0)]
|
||||
pub fn each_path(intr: @ident_interner,
|
||||
cdata: cmd,
|
||||
get_crate_data: GetCrateDataCb,
|
||||
f: &fn(&str, def_like, ast::visibility) -> bool) {
|
||||
_each_path(intr, cdata, get_crate_data, f);
|
||||
}
|
||||
#[cfg(not(stage0))]
|
||||
pub fn each_path(intr: @ident_interner,
|
||||
cdata: cmd,
|
||||
get_crate_data: GetCrateDataCb,
|
||||
|
@ -11,6 +11,8 @@
|
||||
//! This module implements the check that the lifetime of a borrow
|
||||
//! does not exceed the lifetime of the value being borrowed.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use middle::borrowck::*;
|
||||
use mc = middle::mem_categorization;
|
||||
use middle::ty;
|
||||
|
@ -16,6 +16,8 @@
|
||||
// their associated scopes. In phase two, checking loans, we will then make
|
||||
// sure that all of these loans are honored.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use middle::borrowck::*;
|
||||
use mc = middle::mem_categorization;
|
||||
use middle::pat_util;
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
//! Computes the restrictions that result from a borrow.
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use middle::borrowck::*;
|
||||
use mc = middle::mem_categorization;
|
||||
use middle::ty;
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
/*! See doc.rs for a thorough explanation of the borrow checker */
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use mc = middle::mem_categorization;
|
||||
use middle::ty;
|
||||
use middle::typeck;
|
||||
|
@ -22,6 +22,7 @@ use middle::lint::unused_imports;
|
||||
use middle::pat_util::pat_bindings;
|
||||
|
||||
use syntax::ast::*;
|
||||
use syntax::ast;
|
||||
use syntax::ast_util::{def_id_of_def, local_def};
|
||||
use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method};
|
||||
use syntax::ast_util::{Privacy, Public, Private};
|
||||
|
87
src/libstd/rt/global_heap.rs
Normal file
87
src/libstd/rt/global_heap.rs
Normal file
@ -0,0 +1,87 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use sys::{TypeDesc, size_of};
|
||||
use libc::{c_void, size_t, uintptr_t};
|
||||
use c_malloc = libc::malloc;
|
||||
use c_free = libc::free;
|
||||
use managed::raw::{BoxHeaderRepr, BoxRepr};
|
||||
use cast::transmute;
|
||||
use unstable::intrinsics::{atomic_xadd,atomic_xsub};
|
||||
use ptr::null;
|
||||
use intrinsic::TyDesc;
|
||||
|
||||
pub unsafe fn malloc(td: *TypeDesc, size: uint) -> *c_void {
|
||||
assert!(td.is_not_null());
|
||||
|
||||
let total_size = get_box_size(size, (*td).align);
|
||||
let p = c_malloc(total_size as size_t);
|
||||
assert!(p.is_not_null());
|
||||
|
||||
// FIXME #3475: Converting between our two different tydesc types
|
||||
let td: *TyDesc = transmute(td);
|
||||
|
||||
let box: &mut BoxRepr = transmute(p);
|
||||
box.header.ref_count = -1; // Exchange values not ref counted
|
||||
box.header.type_desc = td;
|
||||
box.header.prev = null();
|
||||
box.header.next = null();
|
||||
|
||||
let exchange_count = &mut *exchange_count_ptr();
|
||||
atomic_xadd(exchange_count, 1);
|
||||
|
||||
return transmute(box);
|
||||
}
|
||||
/**
|
||||
Thin wrapper around libc::malloc, none of the box header
|
||||
stuff in exchange_alloc::malloc
|
||||
*/
|
||||
pub unsafe fn malloc_raw(size: uint) -> *c_void {
|
||||
let p = c_malloc(size as size_t);
|
||||
if p.is_null() {
|
||||
fail!("Failure in malloc_raw: result ptr is null");
|
||||
}
|
||||
p
|
||||
}
|
||||
|
||||
pub unsafe fn free(ptr: *c_void) {
|
||||
let exchange_count = &mut *exchange_count_ptr();
|
||||
atomic_xsub(exchange_count, 1);
|
||||
|
||||
assert!(ptr.is_not_null());
|
||||
c_free(ptr);
|
||||
}
|
||||
///Thin wrapper around libc::free, as with exchange_alloc::malloc_raw
|
||||
pub unsafe fn free_raw(ptr: *c_void) {
|
||||
c_free(ptr);
|
||||
}
|
||||
|
||||
fn get_box_size(body_size: uint, body_align: uint) -> uint {
|
||||
let header_size = size_of::<BoxHeaderRepr>();
|
||||
// FIXME (#2699): This alignment calculation is suspicious. Is it right?
|
||||
let total_size = align_to(header_size, body_align) + body_size;
|
||||
return total_size;
|
||||
}
|
||||
|
||||
// Rounds |size| to the nearest |alignment|. Invariant: |alignment| is a power
|
||||
// of two.
|
||||
fn align_to(size: uint, align: uint) -> uint {
|
||||
assert!(align != 0);
|
||||
(size + align - 1) & !(align - 1)
|
||||
}
|
||||
|
||||
fn exchange_count_ptr() -> *mut int {
|
||||
// XXX: Need mutable globals
|
||||
unsafe { transmute(&rust_exchange_count) }
|
||||
}
|
||||
|
||||
extern {
|
||||
static rust_exchange_count: uintptr_t;
|
||||
}
|
492
src/libstd/rt/uv/uvio.rs
Normal file
492
src/libstd/rt/uv/uvio.rs
Normal file
@ -0,0 +1,492 @@
|
||||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use option::*;
|
||||
use result::*;
|
||||
use ops::Drop;
|
||||
use cell::{Cell, empty_cell};
|
||||
use cast::transmute;
|
||||
use clone::Clone;
|
||||
use rt::io::IoError;
|
||||
use rt::io::net::ip::IpAddr;
|
||||
use rt::uv::*;
|
||||
use rt::uv::idle::IdleWatcher;
|
||||
use rt::rtio::*;
|
||||
use rt::sched::Scheduler;
|
||||
use rt::io::{standard_error, OtherIoError};
|
||||
use rt::tube::Tube;
|
||||
use rt::local::Local;
|
||||
|
||||
#[cfg(test)] use container::Container;
|
||||
#[cfg(test)] use uint;
|
||||
#[cfg(test)] use unstable::run_in_bare_thread;
|
||||
#[cfg(test)] use rt::test::*;
|
||||
|
||||
pub struct UvEventLoop {
|
||||
uvio: UvIoFactory
|
||||
}
|
||||
|
||||
pub impl UvEventLoop {
|
||||
fn new() -> UvEventLoop {
|
||||
UvEventLoop {
|
||||
uvio: UvIoFactory(Loop::new())
|
||||
}
|
||||
}
|
||||
|
||||
/// A convenience constructor
|
||||
fn new_scheduler() -> Scheduler {
|
||||
Scheduler::new(~UvEventLoop::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for UvEventLoop {
|
||||
fn finalize(&self) {
|
||||
// XXX: Need mutable finalizer
|
||||
let this = unsafe {
|
||||
transmute::<&UvEventLoop, &mut UvEventLoop>(self)
|
||||
};
|
||||
this.uvio.uv_loop().close();
|
||||
}
|
||||
}
|
||||
|
||||
impl EventLoop for UvEventLoop {
|
||||
|
||||
fn run(&mut self) {
|
||||
self.uvio.uv_loop().run();
|
||||
}
|
||||
|
||||
fn callback(&mut self, f: ~fn()) {
|
||||
let mut idle_watcher = IdleWatcher::new(self.uvio.uv_loop());
|
||||
do idle_watcher.start |idle_watcher, status| {
|
||||
assert!(status.is_none());
|
||||
let mut idle_watcher = idle_watcher;
|
||||
idle_watcher.stop();
|
||||
idle_watcher.close(||());
|
||||
f();
|
||||
}
|
||||
}
|
||||
|
||||
fn callback_ms(&mut self, ms: u64, f: ~fn()) {
|
||||
let mut timer = TimerWatcher::new(self.uvio.uv_loop());
|
||||
do timer.start(ms, 0) |timer, status| {
|
||||
assert!(status.is_none());
|
||||
timer.close(||());
|
||||
f();
|
||||
}
|
||||
}
|
||||
|
||||
fn io<'a>(&'a mut self) -> Option<&'a mut IoFactoryObject> {
|
||||
Some(&mut self.uvio)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_callback_run_once() {
|
||||
do run_in_bare_thread {
|
||||
let mut event_loop = UvEventLoop::new();
|
||||
let mut count = 0;
|
||||
let count_ptr: *mut int = &mut count;
|
||||
do event_loop.callback {
|
||||
unsafe { *count_ptr += 1 }
|
||||
}
|
||||
event_loop.run();
|
||||
assert_eq!(count, 1);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UvIoFactory(Loop);
|
||||
|
||||
pub impl UvIoFactory {
|
||||
fn uv_loop<'a>(&'a mut self) -> &'a mut Loop {
|
||||
match self { &UvIoFactory(ref mut ptr) => ptr }
|
||||
}
|
||||
}
|
||||
|
||||
impl IoFactory for UvIoFactory {
|
||||
// Connect to an address and return a new stream
|
||||
// NB: This blocks the task waiting on the connection.
|
||||
// It would probably be better to return a future
|
||||
fn tcp_connect(&mut self, addr: IpAddr) -> Result<~RtioTcpStreamObject, IoError> {
|
||||
// Create a cell in the task to hold the result. We will fill
|
||||
// the cell before resuming the task.
|
||||
let result_cell = empty_cell();
|
||||
let result_cell_ptr: *Cell<Result<~RtioTcpStreamObject, IoError>> = &result_cell;
|
||||
|
||||
let scheduler = Local::take::<Scheduler>();
|
||||
assert!(scheduler.in_task_context());
|
||||
|
||||
// Block this task and take ownership, switch to scheduler context
|
||||
do scheduler.deschedule_running_task_and_then |task| {
|
||||
|
||||
rtdebug!("connect: entered scheduler context");
|
||||
do Local::borrow::<Scheduler> |scheduler| {
|
||||
assert!(!scheduler.in_task_context());
|
||||
}
|
||||
let mut tcp_watcher = TcpWatcher::new(self.uv_loop());
|
||||
let task_cell = Cell(task);
|
||||
|
||||
// Wait for a connection
|
||||
do tcp_watcher.connect(addr) |stream_watcher, status| {
|
||||
rtdebug!("connect: in connect callback");
|
||||
if status.is_none() {
|
||||
rtdebug!("status is none");
|
||||
let res = Ok(~UvTcpStream { watcher: stream_watcher });
|
||||
|
||||
// Store the stream in the task's stack
|
||||
unsafe { (*result_cell_ptr).put_back(res); }
|
||||
|
||||
// Context switch
|
||||
let scheduler = Local::take::<Scheduler>();
|
||||
scheduler.resume_task_immediately(task_cell.take());
|
||||
} else {
|
||||
rtdebug!("status is some");
|
||||
let task_cell = Cell(task_cell.take());
|
||||
do stream_watcher.close {
|
||||
let res = Err(uv_error_to_io_error(status.get()));
|
||||
unsafe { (*result_cell_ptr).put_back(res); }
|
||||
let scheduler = Local::take::<Scheduler>();
|
||||
scheduler.resume_task_immediately(task_cell.take());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
assert!(!result_cell.is_empty());
|
||||
return result_cell.take();
|
||||
}
|
||||
|
||||
fn tcp_bind(&mut self, addr: IpAddr) -> Result<~RtioTcpListenerObject, IoError> {
|
||||
let mut watcher = TcpWatcher::new(self.uv_loop());
|
||||
match watcher.bind(addr) {
|
||||
Ok(_) => Ok(~UvTcpListener::new(watcher)),
|
||||
Err(uverr) => {
|
||||
let scheduler = Local::take::<Scheduler>();
|
||||
do scheduler.deschedule_running_task_and_then |task| {
|
||||
let task_cell = Cell(task);
|
||||
do watcher.as_stream().close {
|
||||
let scheduler = Local::take::<Scheduler>();
|
||||
scheduler.resume_task_immediately(task_cell.take());
|
||||
}
|
||||
}
|
||||
Err(uv_error_to_io_error(uverr))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME #6090: Prefer newtype structs but Drop doesn't work
|
||||
pub struct UvTcpListener {
|
||||
watcher: TcpWatcher,
|
||||
listening: bool,
|
||||
incoming_streams: Tube<Result<~RtioTcpStreamObject, IoError>>
|
||||
}
|
||||
|
||||
impl UvTcpListener {
|
||||
fn new(watcher: TcpWatcher) -> UvTcpListener {
|
||||
UvTcpListener {
|
||||
watcher: watcher,
|
||||
listening: false,
|
||||
incoming_streams: Tube::new()
|
||||
}
|
||||
}
|
||||
|
||||
fn watcher(&self) -> TcpWatcher { self.watcher }
|
||||
}
|
||||
|
||||
impl Drop for UvTcpListener {
|
||||
fn finalize(&self) {
|
||||
let watcher = self.watcher();
|
||||
let scheduler = Local::take::<Scheduler>();
|
||||
do scheduler.deschedule_running_task_and_then |task| {
|
||||
let task_cell = Cell(task);
|
||||
do watcher.as_stream().close {
|
||||
let scheduler = Local::take::<Scheduler>();
|
||||
scheduler.resume_task_immediately(task_cell.take());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RtioTcpListener for UvTcpListener {
|
||||
|
||||
fn accept(&mut self) -> Result<~RtioTcpStreamObject, IoError> {
|
||||
rtdebug!("entering listen");
|
||||
|
||||
if self.listening {
|
||||
return self.incoming_streams.recv();
|
||||
}
|
||||
|
||||
self.listening = true;
|
||||
|
||||
let server_tcp_watcher = self.watcher();
|
||||
let incoming_streams_cell = Cell(self.incoming_streams.clone());
|
||||
|
||||
let incoming_streams_cell = Cell(incoming_streams_cell.take());
|
||||
let mut server_tcp_watcher = server_tcp_watcher;
|
||||
do server_tcp_watcher.listen |server_stream_watcher, status| {
|
||||
let maybe_stream = if status.is_none() {
|
||||
let mut server_stream_watcher = server_stream_watcher;
|
||||
let mut loop_ = server_stream_watcher.event_loop();
|
||||
let client_tcp_watcher = TcpWatcher::new(&mut loop_);
|
||||
let client_tcp_watcher = client_tcp_watcher.as_stream();
|
||||
// XXX: Need's to be surfaced in interface
|
||||
server_stream_watcher.accept(client_tcp_watcher);
|
||||
Ok(~UvTcpStream { watcher: client_tcp_watcher })
|
||||
} else {
|
||||
Err(standard_error(OtherIoError))
|
||||
};
|
||||
|
||||
let mut incoming_streams = incoming_streams_cell.take();
|
||||
incoming_streams.send(maybe_stream);
|
||||
incoming_streams_cell.put_back(incoming_streams);
|
||||
}
|
||||
|
||||
return self.incoming_streams.recv();
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME #6090: Prefer newtype structs but Drop doesn't work
|
||||
pub struct UvTcpStream {
|
||||
watcher: StreamWatcher
|
||||
}
|
||||
|
||||
impl UvTcpStream {
|
||||
fn watcher(&self) -> StreamWatcher { self.watcher }
|
||||
}
|
||||
|
||||
impl Drop for UvTcpStream {
|
||||
fn finalize(&self) {
|
||||
rtdebug!("closing tcp stream");
|
||||
let watcher = self.watcher();
|
||||
let scheduler = Local::take::<Scheduler>();
|
||||
do scheduler.deschedule_running_task_and_then |task| {
|
||||
let task_cell = Cell(task);
|
||||
do watcher.close {
|
||||
let scheduler = Local::take::<Scheduler>();
|
||||
scheduler.resume_task_immediately(task_cell.take());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RtioTcpStream for UvTcpStream {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<uint, IoError> {
|
||||
let result_cell = empty_cell();
|
||||
let result_cell_ptr: *Cell<Result<uint, IoError>> = &result_cell;
|
||||
|
||||
let scheduler = Local::take::<Scheduler>();
|
||||
assert!(scheduler.in_task_context());
|
||||
let watcher = self.watcher();
|
||||
let buf_ptr: *&mut [u8] = &buf;
|
||||
do scheduler.deschedule_running_task_and_then |task| {
|
||||
rtdebug!("read: entered scheduler context");
|
||||
do Local::borrow::<Scheduler> |scheduler| {
|
||||
assert!(!scheduler.in_task_context());
|
||||
}
|
||||
let mut watcher = watcher;
|
||||
let task_cell = Cell(task);
|
||||
// XXX: We shouldn't reallocate these callbacks every
|
||||
// call to read
|
||||
let alloc: AllocCallback = |_| unsafe {
|
||||
slice_to_uv_buf(*buf_ptr)
|
||||
};
|
||||
do watcher.read_start(alloc) |watcher, nread, _buf, status| {
|
||||
|
||||
// Stop reading so that no read callbacks are
|
||||
// triggered before the user calls `read` again.
|
||||
// XXX: Is there a performance impact to calling
|
||||
// stop here?
|
||||
let mut watcher = watcher;
|
||||
watcher.read_stop();
|
||||
|
||||
let result = if status.is_none() {
|
||||
assert!(nread >= 0);
|
||||
Ok(nread as uint)
|
||||
} else {
|
||||
Err(uv_error_to_io_error(status.unwrap()))
|
||||
};
|
||||
|
||||
unsafe { (*result_cell_ptr).put_back(result); }
|
||||
|
||||
let scheduler = Local::take::<Scheduler>();
|
||||
scheduler.resume_task_immediately(task_cell.take());
|
||||
}
|
||||
}
|
||||
|
||||
assert!(!result_cell.is_empty());
|
||||
return result_cell.take();
|
||||
}
|
||||
|
||||
fn write(&mut self, buf: &[u8]) -> Result<(), IoError> {
|
||||
let result_cell = empty_cell();
|
||||
let result_cell_ptr: *Cell<Result<(), IoError>> = &result_cell;
|
||||
let scheduler = Local::take::<Scheduler>();
|
||||
assert!(scheduler.in_task_context());
|
||||
let watcher = self.watcher();
|
||||
let buf_ptr: *&[u8] = &buf;
|
||||
do scheduler.deschedule_running_task_and_then |task| {
|
||||
let mut watcher = watcher;
|
||||
let task_cell = Cell(task);
|
||||
let buf = unsafe { slice_to_uv_buf(*buf_ptr) };
|
||||
do watcher.write(buf) |_watcher, status| {
|
||||
let result = if status.is_none() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(uv_error_to_io_error(status.unwrap()))
|
||||
};
|
||||
|
||||
unsafe { (*result_cell_ptr).put_back(result); }
|
||||
|
||||
let scheduler = Local::take::<Scheduler>();
|
||||
scheduler.resume_task_immediately(task_cell.take());
|
||||
}
|
||||
}
|
||||
|
||||
assert!(!result_cell.is_empty());
|
||||
return result_cell.take();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_simple_io_no_connect() {
|
||||
do run_in_newsched_task {
|
||||
unsafe {
|
||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
||||
let addr = next_test_ip4();
|
||||
let maybe_chan = (*io).tcp_connect(addr);
|
||||
assert!(maybe_chan.is_err());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_simple_tcp_server_and_client() {
|
||||
do run_in_newsched_task {
|
||||
let addr = next_test_ip4();
|
||||
|
||||
// Start the server first so it's listening when we connect
|
||||
do spawntask_immediately {
|
||||
unsafe {
|
||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
||||
let mut listener = (*io).tcp_bind(addr).unwrap();
|
||||
let mut stream = listener.accept().unwrap();
|
||||
let mut buf = [0, .. 2048];
|
||||
let nread = stream.read(buf).unwrap();
|
||||
assert_eq!(nread, 8);
|
||||
for uint::range(0, nread) |i| {
|
||||
rtdebug!("%u", buf[i] as uint);
|
||||
assert_eq!(buf[i], i as u8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do spawntask_immediately {
|
||||
unsafe {
|
||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
||||
let mut stream = (*io).tcp_connect(addr).unwrap();
|
||||
stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test] #[ignore(reason = "busted")]
|
||||
fn test_read_and_block() {
|
||||
do run_in_newsched_task {
|
||||
let addr = next_test_ip4();
|
||||
|
||||
do spawntask_immediately {
|
||||
let io = unsafe { Local::unsafe_borrow::<IoFactoryObject>() };
|
||||
let mut listener = unsafe { (*io).tcp_bind(addr).unwrap() };
|
||||
let mut stream = listener.accept().unwrap();
|
||||
let mut buf = [0, .. 2048];
|
||||
|
||||
let expected = 32;
|
||||
let mut current = 0;
|
||||
let mut reads = 0;
|
||||
|
||||
while current < expected {
|
||||
let nread = stream.read(buf).unwrap();
|
||||
for uint::range(0, nread) |i| {
|
||||
let val = buf[i] as uint;
|
||||
assert_eq!(val, current % 8);
|
||||
current += 1;
|
||||
}
|
||||
reads += 1;
|
||||
|
||||
let scheduler = Local::take::<Scheduler>();
|
||||
// Yield to the other task in hopes that it
|
||||
// will trigger a read callback while we are
|
||||
// not ready for it
|
||||
do scheduler.deschedule_running_task_and_then |task| {
|
||||
let task = Cell(task);
|
||||
do Local::borrow::<Scheduler> |scheduler| {
|
||||
scheduler.enqueue_task(task.take());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we had multiple reads
|
||||
assert!(reads > 1);
|
||||
}
|
||||
|
||||
do spawntask_immediately {
|
||||
unsafe {
|
||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
||||
let mut stream = (*io).tcp_connect(addr).unwrap();
|
||||
stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
|
||||
stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
|
||||
stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
|
||||
stream.write([0, 1, 2, 3, 4, 5, 6, 7]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_read_read() {
|
||||
do run_in_newsched_task {
|
||||
let addr = next_test_ip4();
|
||||
static MAX: uint = 500000;
|
||||
|
||||
do spawntask_immediately {
|
||||
unsafe {
|
||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
||||
let mut listener = (*io).tcp_bind(addr).unwrap();
|
||||
let mut stream = listener.accept().unwrap();
|
||||
let buf = [1, .. 2048];
|
||||
let mut total_bytes_written = 0;
|
||||
while total_bytes_written < MAX {
|
||||
stream.write(buf);
|
||||
total_bytes_written += buf.len();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do spawntask_immediately {
|
||||
unsafe {
|
||||
let io = Local::unsafe_borrow::<IoFactoryObject>();
|
||||
let mut stream = (*io).tcp_connect(addr).unwrap();
|
||||
let mut buf = [0, .. 2048];
|
||||
let mut total_bytes_read = 0;
|
||||
while total_bytes_read < MAX {
|
||||
let nread = stream.read(buf).unwrap();
|
||||
rtdebug!("read %u bytes", nread as uint);
|
||||
total_bytes_read += nread;
|
||||
for uint::range(0, nread) |i| {
|
||||
assert_eq!(buf[i], 1);
|
||||
}
|
||||
}
|
||||
rtdebug!("read %u bytes total", total_bytes_read as uint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
452
src/libstd/rt/uv/uvll.rs
Normal file
452
src/libstd/rt/uv/uvll.rs
Normal file
@ -0,0 +1,452 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
/*!
|
||||
* Low-level bindings to the libuv library.
|
||||
*
|
||||
* This module contains a set of direct, 'bare-metal' wrappers around
|
||||
* the libuv C-API.
|
||||
*
|
||||
* We're not bothering yet to redefine uv's structs as Rust structs
|
||||
* because they are quite large and change often between versions.
|
||||
* The maintenance burden is just too high. Instead we use the uv's
|
||||
* `uv_handle_size` and `uv_req_size` to find the correct size of the
|
||||
* structs and allocate them on the heap. This can be revisited later.
|
||||
*
|
||||
* There are also a collection of helper functions to ease interacting
|
||||
* with the low-level API.
|
||||
*
|
||||
* As new functionality, existant in uv.h, is added to the rust stdlib,
|
||||
* the mappings should be added in this module.
|
||||
*/
|
||||
|
||||
#[allow(non_camel_case_types)]; // C types
|
||||
|
||||
use libc::{size_t, c_int, c_uint, c_void, c_char, uintptr_t};
|
||||
use libc::{malloc, free};
|
||||
use prelude::*;
|
||||
|
||||
pub static UNKNOWN: c_int = -1;
|
||||
pub static OK: c_int = 0;
|
||||
pub static EOF: c_int = 1;
|
||||
pub static EADDRINFO: c_int = 2;
|
||||
pub static EACCES: c_int = 3;
|
||||
pub static ECONNREFUSED: c_int = 12;
|
||||
pub static ECONNRESET: c_int = 13;
|
||||
pub static EPIPE: c_int = 36;
|
||||
|
||||
pub struct uv_err_t {
|
||||
code: c_int,
|
||||
sys_errno_: c_int
|
||||
}
|
||||
|
||||
pub struct uv_buf_t {
|
||||
base: *u8,
|
||||
len: libc::size_t,
|
||||
}
|
||||
|
||||
pub type uv_handle_t = c_void;
|
||||
pub type uv_loop_t = c_void;
|
||||
pub type uv_idle_t = c_void;
|
||||
pub type uv_tcp_t = c_void;
|
||||
pub type uv_connect_t = c_void;
|
||||
pub type uv_write_t = c_void;
|
||||
pub type uv_async_t = c_void;
|
||||
pub type uv_timer_t = c_void;
|
||||
pub type uv_stream_t = c_void;
|
||||
pub type uv_fs_t = c_void;
|
||||
|
||||
pub type uv_idle_cb = *u8;
|
||||
|
||||
pub type sockaddr_in = c_void;
|
||||
pub type sockaddr_in6 = c_void;
|
||||
|
||||
#[deriving(Eq)]
|
||||
pub enum uv_handle_type {
|
||||
UV_UNKNOWN_HANDLE,
|
||||
UV_ASYNC,
|
||||
UV_CHECK,
|
||||
UV_FS_EVENT,
|
||||
UV_FS_POLL,
|
||||
UV_HANDLE,
|
||||
UV_IDLE,
|
||||
UV_NAMED_PIPE,
|
||||
UV_POLL,
|
||||
UV_PREPARE,
|
||||
UV_PROCESS,
|
||||
UV_STREAM,
|
||||
UV_TCP,
|
||||
UV_TIMER,
|
||||
UV_TTY,
|
||||
UV_UDP,
|
||||
UV_SIGNAL,
|
||||
UV_FILE,
|
||||
UV_HANDLE_TYPE_MAX
|
||||
}
|
||||
|
||||
#[deriving(Eq)]
|
||||
pub enum uv_req_type {
|
||||
UV_UNKNOWN_REQ,
|
||||
UV_REQ,
|
||||
UV_CONNECT,
|
||||
UV_WRITE,
|
||||
UV_SHUTDOWN,
|
||||
UV_UDP_SEND,
|
||||
UV_FS,
|
||||
UV_WORK,
|
||||
UV_GETADDRINFO,
|
||||
UV_REQ_TYPE_MAX
|
||||
}
|
||||
|
||||
pub unsafe fn malloc_handle(handle: uv_handle_type) -> *c_void {
|
||||
assert!(handle != UV_UNKNOWN_HANDLE && handle != UV_HANDLE_TYPE_MAX);
|
||||
let size = rust_uv_handle_size(handle as uint);
|
||||
let p = malloc(size);
|
||||
assert!(p.is_not_null());
|
||||
return p;
|
||||
}
|
||||
|
||||
pub unsafe fn free_handle(v: *c_void) {
|
||||
free(v)
|
||||
}
|
||||
|
||||
pub unsafe fn malloc_req(req: uv_req_type) -> *c_void {
|
||||
assert!(req != UV_UNKNOWN_REQ && req != UV_REQ_TYPE_MAX);
|
||||
let size = rust_uv_req_size(req as uint);
|
||||
let p = malloc(size);
|
||||
assert!(p.is_not_null());
|
||||
return p;
|
||||
}
|
||||
|
||||
pub unsafe fn free_req(v: *c_void) {
|
||||
free(v)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn handle_sanity_check() {
|
||||
unsafe {
|
||||
assert_eq!(UV_HANDLE_TYPE_MAX as uint, rust_uv_handle_type_max());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn request_sanity_check() {
|
||||
unsafe {
|
||||
assert_eq!(UV_REQ_TYPE_MAX as uint, rust_uv_req_type_max());
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn loop_new() -> *c_void {
|
||||
return rust_uv_loop_new();
|
||||
}
|
||||
|
||||
pub unsafe fn loop_delete(loop_handle: *c_void) {
|
||||
rust_uv_loop_delete(loop_handle);
|
||||
}
|
||||
|
||||
pub unsafe fn run(loop_handle: *c_void) {
|
||||
rust_uv_run(loop_handle);
|
||||
}
|
||||
|
||||
pub unsafe fn close<T>(handle: *T, cb: *u8) {
|
||||
rust_uv_close(handle as *c_void, cb);
|
||||
}
|
||||
|
||||
pub unsafe fn walk(loop_handle: *c_void, cb: *u8, arg: *c_void) {
|
||||
rust_uv_walk(loop_handle, cb, arg);
|
||||
}
|
||||
|
||||
pub unsafe fn idle_new() -> *uv_idle_t {
|
||||
rust_uv_idle_new()
|
||||
}
|
||||
|
||||
pub unsafe fn idle_delete(handle: *uv_idle_t) {
|
||||
rust_uv_idle_delete(handle)
|
||||
}
|
||||
|
||||
pub unsafe fn idle_init(loop_handle: *uv_loop_t, handle: *uv_idle_t) -> c_int {
|
||||
rust_uv_idle_init(loop_handle, handle)
|
||||
}
|
||||
|
||||
pub unsafe fn idle_start(handle: *uv_idle_t, cb: uv_idle_cb) -> c_int {
|
||||
rust_uv_idle_start(handle, cb)
|
||||
}
|
||||
|
||||
pub unsafe fn idle_stop(handle: *uv_idle_t) -> c_int {
|
||||
rust_uv_idle_stop(handle)
|
||||
}
|
||||
|
||||
pub unsafe fn tcp_init(loop_handle: *c_void, handle: *uv_tcp_t) -> c_int {
|
||||
return rust_uv_tcp_init(loop_handle, handle);
|
||||
}
|
||||
|
||||
// FIXME ref #2064
|
||||
pub unsafe fn tcp_connect(connect_ptr: *uv_connect_t,
|
||||
tcp_handle_ptr: *uv_tcp_t,
|
||||
addr_ptr: *sockaddr_in,
|
||||
after_connect_cb: *u8) -> c_int {
|
||||
return rust_uv_tcp_connect(connect_ptr, tcp_handle_ptr,
|
||||
after_connect_cb, addr_ptr);
|
||||
}
|
||||
// FIXME ref #2064
|
||||
pub unsafe fn tcp_connect6(connect_ptr: *uv_connect_t,
|
||||
tcp_handle_ptr: *uv_tcp_t,
|
||||
addr_ptr: *sockaddr_in6,
|
||||
after_connect_cb: *u8) -> c_int {
|
||||
return rust_uv_tcp_connect6(connect_ptr, tcp_handle_ptr,
|
||||
after_connect_cb, addr_ptr);
|
||||
}
|
||||
// FIXME ref #2064
|
||||
pub unsafe fn tcp_bind(tcp_server_ptr: *uv_tcp_t, addr_ptr: *sockaddr_in) -> c_int {
|
||||
return rust_uv_tcp_bind(tcp_server_ptr, addr_ptr);
|
||||
}
|
||||
// FIXME ref #2064
|
||||
pub unsafe fn tcp_bind6(tcp_server_ptr: *uv_tcp_t, addr_ptr: *sockaddr_in6) -> c_int {
|
||||
return rust_uv_tcp_bind6(tcp_server_ptr, addr_ptr);
|
||||
}
|
||||
|
||||
pub unsafe fn tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, name: *sockaddr_in) -> c_int {
|
||||
return rust_uv_tcp_getpeername(tcp_handle_ptr, name);
|
||||
}
|
||||
|
||||
pub unsafe fn tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, name: *sockaddr_in6) ->c_int {
|
||||
return rust_uv_tcp_getpeername6(tcp_handle_ptr, name);
|
||||
}
|
||||
|
||||
pub unsafe fn listen<T>(stream: *T, backlog: c_int, cb: *u8) -> c_int {
|
||||
return rust_uv_listen(stream as *c_void, backlog, cb);
|
||||
}
|
||||
|
||||
pub unsafe fn accept(server: *c_void, client: *c_void) -> c_int {
|
||||
return rust_uv_accept(server as *c_void, client as *c_void);
|
||||
}
|
||||
|
||||
pub unsafe fn write<T>(req: *uv_write_t, stream: *T, buf_in: &[uv_buf_t], cb: *u8) -> c_int {
|
||||
let buf_ptr = vec::raw::to_ptr(buf_in);
|
||||
let buf_cnt = buf_in.len() as i32;
|
||||
return rust_uv_write(req as *c_void, stream as *c_void, buf_ptr, buf_cnt, cb);
|
||||
}
|
||||
pub unsafe fn read_start(stream: *uv_stream_t, on_alloc: *u8, on_read: *u8) -> c_int {
|
||||
return rust_uv_read_start(stream as *c_void, on_alloc, on_read);
|
||||
}
|
||||
|
||||
pub unsafe fn read_stop(stream: *uv_stream_t) -> c_int {
|
||||
return rust_uv_read_stop(stream as *c_void);
|
||||
}
|
||||
|
||||
pub unsafe fn last_error(loop_handle: *c_void) -> uv_err_t {
|
||||
return rust_uv_last_error(loop_handle);
|
||||
}
|
||||
|
||||
pub unsafe fn strerror(err: *uv_err_t) -> *c_char {
|
||||
return rust_uv_strerror(err);
|
||||
}
|
||||
pub unsafe fn err_name(err: *uv_err_t) -> *c_char {
|
||||
return rust_uv_err_name(err);
|
||||
}
|
||||
|
||||
pub unsafe fn async_init(loop_handle: *c_void, async_handle: *uv_async_t, cb: *u8) -> c_int {
|
||||
return rust_uv_async_init(loop_handle, async_handle, cb);
|
||||
}
|
||||
|
||||
pub unsafe fn async_send(async_handle: *uv_async_t) {
|
||||
return rust_uv_async_send(async_handle);
|
||||
}
|
||||
pub unsafe fn buf_init(input: *u8, len: uint) -> uv_buf_t {
|
||||
let out_buf = uv_buf_t { base: ptr::null(), len: 0 as size_t };
|
||||
let out_buf_ptr = ptr::to_unsafe_ptr(&out_buf);
|
||||
rust_uv_buf_init(out_buf_ptr, input, len as size_t);
|
||||
return out_buf;
|
||||
}
|
||||
|
||||
pub unsafe fn timer_init(loop_ptr: *c_void, timer_ptr: *uv_timer_t) -> c_int {
|
||||
return rust_uv_timer_init(loop_ptr, timer_ptr);
|
||||
}
|
||||
pub unsafe fn timer_start(timer_ptr: *uv_timer_t, cb: *u8, timeout: u64,
|
||||
repeat: u64) -> c_int {
|
||||
return rust_uv_timer_start(timer_ptr, cb, timeout, repeat);
|
||||
}
|
||||
pub unsafe fn timer_stop(timer_ptr: *uv_timer_t) -> c_int {
|
||||
return rust_uv_timer_stop(timer_ptr);
|
||||
}
|
||||
|
||||
pub unsafe fn malloc_ip4_addr(ip: &str, port: int) -> *sockaddr_in {
|
||||
do str::as_c_str(ip) |ip_buf| {
|
||||
rust_uv_ip4_addrp(ip_buf as *u8, port as libc::c_int)
|
||||
}
|
||||
}
|
||||
pub unsafe fn malloc_ip6_addr(ip: &str, port: int) -> *sockaddr_in6 {
|
||||
do str::as_c_str(ip) |ip_buf| {
|
||||
rust_uv_ip6_addrp(ip_buf as *u8, port as libc::c_int)
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn free_ip4_addr(addr: *sockaddr_in) {
|
||||
rust_uv_free_ip4_addr(addr);
|
||||
}
|
||||
|
||||
pub unsafe fn free_ip6_addr(addr: *sockaddr_in6) {
|
||||
rust_uv_free_ip6_addr(addr);
|
||||
}
|
||||
|
||||
// data access helpers
|
||||
pub unsafe fn get_loop_for_uv_handle<T>(handle: *T) -> *c_void {
|
||||
return rust_uv_get_loop_for_uv_handle(handle as *c_void);
|
||||
}
|
||||
pub unsafe fn get_stream_handle_from_connect_req(connect: *uv_connect_t) -> *uv_stream_t {
|
||||
return rust_uv_get_stream_handle_from_connect_req(connect);
|
||||
}
|
||||
pub unsafe fn get_stream_handle_from_write_req(write_req: *uv_write_t) -> *uv_stream_t {
|
||||
return rust_uv_get_stream_handle_from_write_req(write_req);
|
||||
}
|
||||
pub unsafe fn get_data_for_uv_loop(loop_ptr: *c_void) -> *c_void {
|
||||
rust_uv_get_data_for_uv_loop(loop_ptr)
|
||||
}
|
||||
pub unsafe fn set_data_for_uv_loop(loop_ptr: *c_void, data: *c_void) {
|
||||
rust_uv_set_data_for_uv_loop(loop_ptr, data);
|
||||
}
|
||||
pub unsafe fn get_data_for_uv_handle<T>(handle: *T) -> *c_void {
|
||||
return rust_uv_get_data_for_uv_handle(handle as *c_void);
|
||||
}
|
||||
pub unsafe fn set_data_for_uv_handle<T, U>(handle: *T, data: *U) {
|
||||
rust_uv_set_data_for_uv_handle(handle as *c_void, data as *c_void);
|
||||
}
|
||||
pub unsafe fn get_data_for_req<T>(req: *T) -> *c_void {
|
||||
return rust_uv_get_data_for_req(req as *c_void);
|
||||
}
|
||||
pub unsafe fn set_data_for_req<T, U>(req: *T, data: *U) {
|
||||
rust_uv_set_data_for_req(req as *c_void, data as *c_void);
|
||||
}
|
||||
pub unsafe fn get_base_from_buf(buf: uv_buf_t) -> *u8 {
|
||||
return rust_uv_get_base_from_buf(buf);
|
||||
}
|
||||
pub unsafe fn get_len_from_buf(buf: uv_buf_t) -> size_t {
|
||||
return rust_uv_get_len_from_buf(buf);
|
||||
}
|
||||
pub unsafe fn malloc_buf_base_of(suggested_size: size_t) -> *u8 {
|
||||
return rust_uv_malloc_buf_base_of(suggested_size);
|
||||
}
|
||||
pub unsafe fn free_base_of_buf(buf: uv_buf_t) {
|
||||
rust_uv_free_base_of_buf(buf);
|
||||
}
|
||||
|
||||
pub unsafe fn get_last_err_info(uv_loop: *c_void) -> ~str {
|
||||
let err = last_error(uv_loop);
|
||||
let err_ptr = ptr::to_unsafe_ptr(&err);
|
||||
let err_name = str::raw::from_c_str(err_name(err_ptr));
|
||||
let err_msg = str::raw::from_c_str(strerror(err_ptr));
|
||||
return fmt!("LIBUV ERROR: name: %s msg: %s",
|
||||
err_name, err_msg);
|
||||
}
|
||||
|
||||
pub unsafe fn get_last_err_data(uv_loop: *c_void) -> uv_err_data {
|
||||
let err = last_error(uv_loop);
|
||||
let err_ptr = ptr::to_unsafe_ptr(&err);
|
||||
let err_name = str::raw::from_c_str(err_name(err_ptr));
|
||||
let err_msg = str::raw::from_c_str(strerror(err_ptr));
|
||||
uv_err_data { err_name: err_name, err_msg: err_msg }
|
||||
}
|
||||
|
||||
pub struct uv_err_data {
|
||||
err_name: ~str,
|
||||
err_msg: ~str,
|
||||
}
|
||||
|
||||
extern {
|
||||
|
||||
fn rust_uv_handle_size(type_: uintptr_t) -> size_t;
|
||||
fn rust_uv_req_size(type_: uintptr_t) -> size_t;
|
||||
fn rust_uv_handle_type_max() -> uintptr_t;
|
||||
fn rust_uv_req_type_max() -> uintptr_t;
|
||||
|
||||
// libuv public API
|
||||
fn rust_uv_loop_new() -> *c_void;
|
||||
fn rust_uv_loop_delete(lp: *c_void);
|
||||
fn rust_uv_run(loop_handle: *c_void);
|
||||
fn rust_uv_close(handle: *c_void, cb: *u8);
|
||||
fn rust_uv_walk(loop_handle: *c_void, cb: *u8, arg: *c_void);
|
||||
|
||||
fn rust_uv_idle_new() -> *uv_idle_t;
|
||||
fn rust_uv_idle_delete(handle: *uv_idle_t);
|
||||
fn rust_uv_idle_init(loop_handle: *uv_loop_t, handle: *uv_idle_t) -> c_int;
|
||||
fn rust_uv_idle_start(handle: *uv_idle_t, cb: uv_idle_cb) -> c_int;
|
||||
fn rust_uv_idle_stop(handle: *uv_idle_t) -> c_int;
|
||||
|
||||
fn rust_uv_async_send(handle: *uv_async_t);
|
||||
fn rust_uv_async_init(loop_handle: *c_void,
|
||||
async_handle: *uv_async_t,
|
||||
cb: *u8) -> c_int;
|
||||
fn rust_uv_tcp_init(loop_handle: *c_void, handle_ptr: *uv_tcp_t) -> c_int;
|
||||
// FIXME ref #2604 .. ?
|
||||
fn rust_uv_buf_init(out_buf: *uv_buf_t, base: *u8, len: size_t);
|
||||
fn rust_uv_last_error(loop_handle: *c_void) -> uv_err_t;
|
||||
// FIXME ref #2064
|
||||
fn rust_uv_strerror(err: *uv_err_t) -> *c_char;
|
||||
// FIXME ref #2064
|
||||
fn rust_uv_err_name(err: *uv_err_t) -> *c_char;
|
||||
fn rust_uv_ip4_addrp(ip: *u8, port: c_int) -> *sockaddr_in;
|
||||
fn rust_uv_ip6_addrp(ip: *u8, port: c_int) -> *sockaddr_in6;
|
||||
fn rust_uv_free_ip4_addr(addr: *sockaddr_in);
|
||||
fn rust_uv_free_ip6_addr(addr: *sockaddr_in6);
|
||||
fn rust_uv_ip4_name(src: *sockaddr_in, dst: *u8, size: size_t) -> c_int;
|
||||
fn rust_uv_ip6_name(src: *sockaddr_in6, dst: *u8, size: size_t) -> c_int;
|
||||
fn rust_uv_ip4_port(src: *sockaddr_in) -> c_uint;
|
||||
fn rust_uv_ip6_port(src: *sockaddr_in6) -> c_uint;
|
||||
// FIXME ref #2064
|
||||
fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t,
|
||||
tcp_handle_ptr: *uv_tcp_t,
|
||||
after_cb: *u8,
|
||||
addr: *sockaddr_in) -> c_int;
|
||||
// FIXME ref #2064
|
||||
fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t, addr: *sockaddr_in) -> c_int;
|
||||
// FIXME ref #2064
|
||||
fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t,
|
||||
tcp_handle_ptr: *uv_tcp_t,
|
||||
after_cb: *u8,
|
||||
addr: *sockaddr_in6) -> c_int;
|
||||
// FIXME ref #2064
|
||||
fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t, addr: *sockaddr_in6) -> c_int;
|
||||
fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t,
|
||||
name: *sockaddr_in) -> c_int;
|
||||
fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t,
|
||||
name: *sockaddr_in6) ->c_int;
|
||||
fn rust_uv_listen(stream: *c_void, backlog: c_int, cb: *u8) -> c_int;
|
||||
fn rust_uv_accept(server: *c_void, client: *c_void) -> c_int;
|
||||
fn rust_uv_write(req: *c_void,
|
||||
stream: *c_void,
|
||||
buf_in: *uv_buf_t,
|
||||
buf_cnt: c_int,
|
||||
cb: *u8) -> c_int;
|
||||
fn rust_uv_read_start(stream: *c_void,
|
||||
on_alloc: *u8,
|
||||
on_read: *u8) -> c_int;
|
||||
fn rust_uv_read_stop(stream: *c_void) -> c_int;
|
||||
fn rust_uv_timer_init(loop_handle: *c_void,
|
||||
timer_handle: *uv_timer_t) -> c_int;
|
||||
fn rust_uv_timer_start(timer_handle: *uv_timer_t,
|
||||
cb: *u8,
|
||||
timeout: libc::uint64_t,
|
||||
repeat: libc::uint64_t) -> c_int;
|
||||
fn rust_uv_timer_stop(handle: *uv_timer_t) -> c_int;
|
||||
|
||||
fn rust_uv_malloc_buf_base_of(sug_size: size_t) -> *u8;
|
||||
fn rust_uv_free_base_of_buf(buf: uv_buf_t);
|
||||
fn rust_uv_get_stream_handle_from_connect_req(connect_req: *uv_connect_t) -> *uv_stream_t;
|
||||
fn rust_uv_get_stream_handle_from_write_req(write_req: *uv_write_t) -> *uv_stream_t;
|
||||
fn rust_uv_get_loop_for_uv_handle(handle: *c_void) -> *c_void;
|
||||
fn rust_uv_get_data_for_uv_loop(loop_ptr: *c_void) -> *c_void;
|
||||
fn rust_uv_set_data_for_uv_loop(loop_ptr: *c_void, data: *c_void);
|
||||
fn rust_uv_get_data_for_uv_handle(handle: *c_void) -> *c_void;
|
||||
fn rust_uv_set_data_for_uv_handle(handle: *c_void, data: *c_void);
|
||||
fn rust_uv_get_data_for_req(req: *c_void) -> *c_void;
|
||||
fn rust_uv_set_data_for_req(req: *c_void, data: *c_void);
|
||||
fn rust_uv_get_base_from_buf(buf: uv_buf_t) -> *u8;
|
||||
fn rust_uv_get_len_from_buf(buf: uv_buf_t) -> size_t;
|
||||
}
|
@ -16,6 +16,8 @@
|
||||
* other useful things like `push()` and `len()`.
|
||||
*/
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::old_iter;
|
||||
use core::old_iter::BaseIter;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user