On 01/24/2013 04:37 PM, Patrick Walton wrote:
On 1/24/13 3:55 PM, Michael Neumann wrote:
* I don't like the way libuv is currently integrated into the system. It
I sympathize.
works, but performance is
quite low and IMHO the blocking interface is not very usable. For
example I want to write a process
that accepts messages from other processes, and then writes something to
the socket or reads from
the socket. This will currently not work, as reading from the socket
will block the process, and
then no more requests can be sent to the process.
So instead of using the read() / write() API of an io::Reader, I'd
prefer to expose the read/write
events of libuv via messages (this is already done between the iotask
and the read()/write() methods,
but it is not accessible to the "end-user").
So instead of:
io.read(...)
one would simply write:
readport.recv()
Both of these are blocking. The significant advantage of using a port
here though is that core::pipes has several ways to receive on multiple
ports at once, so you could wait for both the read event and some other
signal instead of being stuck until the read either succeeds or times out.
There is a lot of overlap functionally between Port/Chan and
Reader/Writer (std::flatpipes event implements the GenericPort and
GenericChan traits on top of Reader and Writer). They both have their
strengths though. Streaming data over channels is just going to leave
you with a bunch of byte buffers, whereas Readers give you lots of
control over how to interpret those bytes. I could see the api here
being channel based, letting the user opt into Reader and Writer
implementations for Port<~[u8]> etc. as needed.
The same for writes. EOF results in closing the readport. The question
is how these messages
should look like to be usable for the programmer (how to handle
errors?).
What do you think?
Actually there would be connecting ports, which receive events whenever
a new connection is established.
A successfully established connection would then be represented by a
readport and writechannel.
brson is working on a rewrite of the scheduler. This new scheduler
should run directly on the libuv event loop. This should have much
higher performance.
The current implementation will go away completely. It was useful as a
prototype but it has problems. The new intent is to design the Rust
scheduler so that it can be driven by an arbitrary event loop, then use
the uv event loop for that purpose by default (this could also be useful
for e.g. integrating with the Win32 event loop, etc.). The main
advantage of integrating uv into the scheduler over the current design
is that there will be much less synchronization and context switching to
dispatch events. This will unfortunately necessitate a complex
integration of the scheduler and the I/O system and I don't know how
that is going to work yet.
* I'd like to know more how the task scheduler and the pipes work
together. Is there any info available somewhere?
I think brson knows best.
There's no info besides the source code. The relevant files are
`src/libcore/pipes.rs` and `src/rt/rust_task.cpp`. Pipes uses three
foreign calls to indirectly control the scheduler: `task_wait_event`,
`task_signal_event`, `task_clear_event_reject`, the details of which I
don't know off hand but which look fairly straightforward. The
implementation is made more complex by the continued existence of
`core::oldcomm`, which uses a slightly different method of signalling
events and relies on much more foreign code.
Also, if I would create a native pthread in C, could I simply call an
external rust function?
Not yet. Today all Rust code depends on the Rust runtime (I've been
saying that code must be run 'in task context'). Creating a pthread puts
you outside of a task context. Being in task context essentially means
that various runtime calls are able to locate a pointer to `rust_task`
in TLS, and of course that pointer must be set up and managed correctly.
It's not something you can do manually.
We are slowly working on 'freestanding Rust', which will let you run
Rust code without the runtime. This is particularly needed at the moment
to port the Rust runtime to Rust. The first steps are in this pull request:
https://github.com/mozilla/rust/pull/4619
After that pull request you can make foreign calls and use the exchange
heap outside of task context, but if you do call a function that
requires the runtime the process will abort.
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev