On 01/28/2013 05:29 PM, Graydon Hoare wrote:
On 13-01-28 04:56 PM, Brian Anderson wrote:
I think libuv is doing too much here. For example, if I don't want to
remove the socket from the event
queue, just disable the callback, then this is not possible. I'd
prefer when I could just tell libuv that
I am interested in event X (on Windows: I/O completion, on UNIX: I/O
availability).
Yet the optimization you suggest has to do with recycling the buffer,
not listening for one kind of event vs. another.
In general I'm not interested in trying to "get underneath" the
abstraction uv is providing. It's providing an IOCP-oriented interface,
I would like to code to that and make the rust IO library not have to
worry when it's on windows vs. unix. That's the point of the abstraction
uv provides, and it's valuable. If it means bouncing off epoll a few too
many times (or reallocating a buffer a few too many times), I'm not too
concerned. Those should both be O(1) operations.
Is it possible to do this optimization later or do we need to plan for
this ahead of time? I would prefer to use the uv API as it's presented
to start with.
The optimization to use a caller-provided buffer should (a) not be
necessary to get us started and (b) be equally possible on either
platform, unix or windows, _so long as_ we're actually sleeping a task
during its period of interest in IO (either the pre-readiness sleep or a
post-issue, pre-completion sleep). In other words, if we're simulating
sync IO, then we can use a task-local buffer. If we're _not_ simulating
sync IO (I sure hope we do!) then we should let uv allocate and free
dynamic buffers as it needs them.
But I really hope we wind up structuring it so it simulates sync IO.
We're providing a task abstraction. Users _want_ the sync IO abstraction
the same way they want the sequential control flow abstraction.
Presenting the scheduler-originating I/O as synchronous is what I
intend. I am not sure that we can guarantee that a task is actually
waiting for I/O when an I/O event occurs that that task is waiting for.
A task may block on some other unrelated event while the event loop is
doing I/O. Pseudocode:
let port = IOPort::connect(); // Assume we're doing I/O reads using
something portlike
while port.recv() {
// Block on a different port, while uv continues doing I/O on our
behalf
let intermediate_value = some_other_port.recv();
}
This is why I'm imagining that the scheduler will sometimes need to buffer.
(Indeed, on an appropriately-behaving system I fully expect task=thread
and sync IO calls=system calls)
I welcome any help here. One important and big step we need to get
through before trying to integrate uv into the scheduler is to create
safe Rust bindings to libuv. Last time around we coded directly to the
uv API and it resulted in some big maintenance problems (unsafe code
everywhere). pfox is working on updating libuv to upstream trunk now,
after which I expect somebody will start on the bindings. If you want to
discuss the integration of uv into the scheduler there is an issue open:
https://github.com/mozilla/rust/issues/4419.
I'll try to remain more-involved this time. We have to get this right.
-Graydon
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev