On Thu, Nov 14, 2013 at 5:19 PM, Brian Anderson <[email protected]> wrote:
> On 11/14/2013 04:03 PM, Diego Ongaro wrote:
>>
>> My program starts a bunch of tasks, then I want the main task to both
>> receive ctrl-c signals and receive results from the children. The
>> signal will come from a std::rt::io::signal::Listener's port, which is
>> an std::comm::Port<Signum>. The child results will come from a
>> std::comm::Port<~[uint]>.
>>
>> My first problem is that std::comm::Port doesn't implement
>> std::select::Select. It looks like std::rt::comm::Port does, and
>> std::comm::Port is just a small wrapper around that, but
>> std::comm::Port makes its internal std::rt::comm::Port private. Is
>> there any way to select on a std::comm::Port? (And what's the
>> difference between a std::rt::comm::Port and a std::comm::Port?)
>
>
> There currently isn't a way - this feature isn't fully baked yet, but it
> should not take a whole lot of effort to get it working. There is no
> functional difference between std::comm and std::rt::comm; std::rt::comm
> should be moved wholesale to std::comm and the current std::comm deleted,
> but it hasn't been done yet.
Ok. In the meantime until std::comm gets blown away, can we comment
out the "priv" keyword in it? I've attached a patch that does this.
This patch would be enough to allow me and others to work around this
issue for now (see below).
>> My second problem is that std::select::select() doesn't seem to
>> support selecting from ports with different types. Naively, I tried
>> select([p1, p2]), but that expects p1 and p2 to have the same type:
>> error: mismatched types: expected
>> `std::rt::comm::Port<std::rt::io::signal::Signum>` but found
>> `std::rt::comm::Port<~[uint]>` (expected enum
>> std::rt::io::signal::Signum but found vector)
>> It'll need dynamic dispatch, so I tried: select([p1 as &Select, p2 as
>> &Select]). However, this doesn't work since &Select doesn't implement
>> Select:
>> error: failed to find an implementation of trait std::select::Select
>> for &std::select::Select<no-bounds>
>>
>> There's some commented out code that may be related in select.rs,
>> though it's hard for me to know where this stands:
>> /* FIXME(#5121, #7914) This all should be legal, but rust is not
>> clever enough yet.
>>
>> impl <'self> Select for &'self mut Select {
>> fn optimistic_check(&mut self) -> bool { self.optimistic_check() }
>> fn block_on(&mut self, sched: &mut Scheduler, task: BlockedTask) ->
>> bool {
>> self.block_on(sched, task)
>> }
>> fn unblock_from(&mut self) -> bool { self.unblock_from() }
>> }
>> ...
>>
>> How can I select on two ports of different types?
>
>
> My understanding is that this code needs to be enabled to make select on
> heterogenous types work correctly. I do not know the details of this code
> but it appears that Niko has not landed a fix for #5121 yet. Contributions
> here are very welcome.
I think this is beyond my understanding of Rust internals for now
(though hey, just started with Rust this week, who knows). I didn't
spend much time on it, but I wasn't able to get this code to work by
just removing the comments. Instead, I have a workaround that does the
job for me once the attached patch is applied. It creates a wrapper
struct called SelectBox which implements Select by forwarding all
methods of SelectInner to an &'self mut Select field. Then I created a
macro to make the syntax tolerable. That's all available at
https://gist.github.com/ongardie/7494388 along with an example.
Best,
Diego
From bf9e31e2a0a44630c0aeee1a76818427b95d0d43 Mon Sep 17 00:00:00 2001
From: Diego Ongaro <[email protected]>
Date: Fri, 15 Nov 2013 16:34:28 -0800
Subject: [PATCH] Disable priv in std::comm::Port, etc
It's useful to allow users to get at the internal std::rc::comm::Port,
and other such fields, since they implement important traits like
Select.
---
src/libstd/comm.rs | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs
index 038598a..3a7b640 100644
--- a/src/libstd/comm.rs
+++ b/src/libstd/comm.rs
@@ -55,16 +55,17 @@ pub trait Peekable<T> {
fn peek(&self) -> bool;
}
-pub struct PortOne<T> { priv x: rtcomm::PortOne<T> }
-pub struct ChanOne<T> { priv x: rtcomm::ChanOne<T> }
+/* priv is disabled to allow users to get at traits like Select. */
+pub struct PortOne<T> { /* priv */ x: rtcomm::PortOne<T> }
+pub struct ChanOne<T> { /* priv */ x: rtcomm::ChanOne<T> }
pub fn oneshot<T: Send>() -> (PortOne<T>, ChanOne<T>) {
let (p, c) = rtcomm::oneshot();
(PortOne { x: p }, ChanOne { x: c })
}
-pub struct Port<T> { priv x: rtcomm::Port<T> }
-pub struct Chan<T> { priv x: rtcomm::Chan<T> }
+pub struct Port<T> { /* priv */ x: rtcomm::Port<T> }
+pub struct Chan<T> { /* priv */ x: rtcomm::Chan<T> }
pub fn stream<T: Send>() -> (Port<T>, Chan<T>) {
let (p, c) = rtcomm::stream();
@@ -158,7 +159,7 @@ impl<T: Send> Peekable<T> for Port<T> {
}
-pub struct SharedChan<T> { priv x: rtcomm::SharedChan<T> }
+pub struct SharedChan<T> { /* priv */ x: rtcomm::SharedChan<T> }
impl<T: Send> SharedChan<T> {
pub fn new(c: Chan<T>) -> SharedChan<T> {
@@ -200,7 +201,7 @@ impl<T: Send> Clone for SharedChan<T> {
}
}
-pub struct SharedPort<T> { priv x: rtcomm::SharedPort<T> }
+pub struct SharedPort<T> { /* priv */ x: rtcomm::SharedPort<T> }
impl<T: Send> SharedPort<T> {
pub fn new(p: Port<T>) -> SharedPort<T> {
--
1.8.4.rc3
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev