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

Reply via email to