diff options
| author | Eric Holk <eholk@mozilla.com> | 2011-07-29 11:00:44 -0700 |
|---|---|---|
| committer | Graydon Hoare <graydon@mozilla.com> | 2011-07-29 18:54:59 -0700 |
| commit | d1dbb99984064eedb77c0f55300430bcb35ce109 (patch) | |
| tree | 9e45ab1c525f0c59ac892117d0dd5424d29a7f51 /src/rt/rust_chan.cpp | |
| parent | bc4e9afe2547fa88b55ffc31fef041dffe864b2b (diff) | |
| download | rust-d1dbb99984064eedb77c0f55300430bcb35ce109.tar.gz rust-d1dbb99984064eedb77c0f55300430bcb35ce109.zip | |
Removing proxies and message queues.
Diffstat (limited to 'src/rt/rust_chan.cpp')
| -rw-r--r-- | src/rt/rust_chan.cpp | 107 |
1 files changed, 39 insertions, 68 deletions
diff --git a/src/rt/rust_chan.cpp b/src/rt/rust_chan.cpp index 9017e9a2bc1..3ade237c25a 100644 --- a/src/rt/rust_chan.cpp +++ b/src/rt/rust_chan.cpp @@ -4,7 +4,7 @@ /** * Create a new rust channel and associate it with the specified port. */ -rust_chan::rust_chan(rust_kernel *kernel, maybe_proxy<rust_port> *port, +rust_chan::rust_chan(rust_kernel *kernel, rust_port *port, size_t unit_sz) : ref_count(1), kernel(kernel), @@ -29,18 +29,16 @@ rust_chan::~rust_chan() { /** * Link this channel with the specified port. */ -void rust_chan::associate(maybe_proxy<rust_port> *port) { +void rust_chan::associate(rust_port *port) { this->port = port; - if (port->is_proxy() == false) { - scoped_lock with(port->referent()->lock); - KLOG(kernel, task, - "associating chan: 0x%" PRIxPTR " with port: 0x%" PRIxPTR, - this, port); - ++this->ref_count; - this->task = port->referent()->task; - this->task->ref(); - this->port->referent()->chans.push(this); - } + scoped_lock with(port->lock); + KLOG(kernel, task, + "associating chan: 0x%" PRIxPTR " with port: 0x%" PRIxPTR, + this, port); + ++this->ref_count; + this->task = port->task; + this->task->ref(); + this->port->chans.push(this); } bool rust_chan::is_associated() { @@ -52,19 +50,17 @@ bool rust_chan::is_associated() { */ void rust_chan::disassociate() { A(kernel, - port->referent()->lock.lock_held_by_current_thread(), + port->lock.lock_held_by_current_thread(), "Port referent lock must be held to call rust_chan::disassociate"); A(kernel, is_associated(), "Channel must be associated with a port."); - if (port->is_proxy() == false) { - KLOG(kernel, task, - "disassociating chan: 0x%" PRIxPTR " from port: 0x%" PRIxPTR, - this, port->referent()); - --this->ref_count; - task->deref(); - this->task = NULL; - port->referent()->chans.swap_delete(this); - } + KLOG(kernel, task, + "disassociating chan: 0x%" PRIxPTR " from port: 0x%" PRIxPTR, + this, port); + --this->ref_count; + task->deref(); + this->task = NULL; + port->chans.swap_delete(this); // Delete reference to the port. port = NULL; @@ -74,12 +70,7 @@ void rust_chan::disassociate() { * Attempt to send data to the associated port. */ void rust_chan::send(void *sptr) { - I(kernel, !port->is_proxy()); - - rust_port *target_port = port->referent(); - // TODO: We can probably avoid this lock by using atomic operations in - // circular_buffer. - scoped_lock with(target_port->lock); + scoped_lock with(port->lock); buffer.enqueue(sptr); @@ -92,28 +83,17 @@ void rust_chan::send(void *sptr) { A(kernel, !buffer.is_empty(), "rust_chan::transmit with nothing to send."); - if (port->is_proxy()) { - data_message::send(buffer.peek(), buffer.unit_sz, "send data", - task->get_handle(), port->as_proxy()->handle()); - buffer.dequeue(NULL); - } else { - if (target_port->task->blocked_on(target_port)) { - KLOG(kernel, comm, "dequeued in rendezvous_ptr"); - buffer.dequeue(target_port->task->rendezvous_ptr); - target_port->task->rendezvous_ptr = 0; - target_port->task->wakeup(target_port); - return; - } + if (port->task->blocked_on(port)) { + KLOG(kernel, comm, "dequeued in rendezvous_ptr"); + buffer.dequeue(port->task->rendezvous_ptr); + port->task->rendezvous_ptr = 0; + port->task->wakeup(port); } - - return; } rust_chan *rust_chan::clone(rust_task *target) { - size_t unit_sz = buffer.unit_sz; - maybe_proxy<rust_port> *port = this->port; return new (target->kernel, "cloned chan") - rust_chan(kernel, port, unit_sz); + rust_chan(kernel, port, buffer.unit_sz); } /** @@ -125,30 +105,21 @@ void rust_chan::destroy() { "Channel's ref count should be zero."); if (is_associated()) { - if (port->is_proxy()) { - // Here is a good place to delete the port proxy we allocated - // in upcall_clone_chan. - rust_proxy<rust_port> *proxy = port->as_proxy(); - scoped_lock with(port->referent()->lock); - disassociate(); - delete proxy; - } else { - // We're trying to delete a channel that another task may be - // reading from. We have two options: - // - // 1. We can flush the channel by blocking in upcall_flush_chan() - // and resuming only when the channel is flushed. The problem - // here is that we can get ourselves in a deadlock if the - // parent task tries to join us. - // - // 2. We can leave the channel in a "dormnat" state by not freeing - // it and letting the receiver task delete it for us instead. - if (buffer.is_empty() == false) { - return; - } - scoped_lock with(port->referent()->lock); - disassociate(); + // We're trying to delete a channel that another task may be + // reading from. We have two options: + // + // 1. We can flush the channel by blocking in upcall_flush_chan() + // and resuming only when the channel is flushed. The problem + // here is that we can get ourselves in a deadlock if the + // parent task tries to join us. + // + // 2. We can leave the channel in a "dormnat" state by not freeing + // it and letting the receiver task delete it for us instead. + if (buffer.is_empty() == false) { + return; } + scoped_lock with(port->lock); + disassociate(); } delete this; } |
