2010-06-23 21:03:09 -07:00
|
|
|
#include "rust_internal.h"
|
|
|
|
#include "rust_chan.h"
|
|
|
|
|
|
|
|
rust_chan::rust_chan(rust_task *task, rust_port *port) :
|
2010-07-19 14:05:18 -07:00
|
|
|
task(task), port(port), buffer(task->dom, port->unit_sz), token(this) {
|
|
|
|
|
|
|
|
if (port) {
|
2010-06-23 21:03:09 -07:00
|
|
|
port->chans.push(this);
|
2010-07-19 14:05:18 -07:00
|
|
|
ref();
|
|
|
|
}
|
|
|
|
|
|
|
|
task->log(rust_log::MEM | rust_log::COMM,
|
|
|
|
"new rust_chan(task=0x%" PRIxPTR
|
2010-07-28 00:11:28 -07:00
|
|
|
", port=0x%" PRIxPTR ") -> chan=0x%" PRIxPTR,
|
|
|
|
(uintptr_t) task, (uintptr_t) port, (uintptr_t) this);
|
2010-06-23 21:03:09 -07:00
|
|
|
}
|
|
|
|
|
2010-07-19 14:05:18 -07:00
|
|
|
rust_chan::~rust_chan() {
|
2010-06-23 21:03:09 -07:00
|
|
|
if (port) {
|
|
|
|
if (token.pending())
|
|
|
|
token.withdraw();
|
2010-07-19 14:05:18 -07:00
|
|
|
port->chans.swap_delete(this);
|
2010-06-23 21:03:09 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-19 14:05:18 -07:00
|
|
|
void rust_chan::disassociate() {
|
2010-06-23 21:03:09 -07:00
|
|
|
I(task->dom, port);
|
|
|
|
|
|
|
|
if (token.pending())
|
|
|
|
token.withdraw();
|
|
|
|
|
|
|
|
// Delete reference to the port/
|
|
|
|
port = NULL;
|
2010-07-19 14:05:18 -07:00
|
|
|
|
|
|
|
deref();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Attempt to transmit channel data to the associated port.
|
|
|
|
*/
|
|
|
|
int rust_chan::transmit() {
|
|
|
|
rust_dom *dom = task->dom;
|
|
|
|
|
|
|
|
// TODO: Figure out how and why the port would become null.
|
|
|
|
if (port == NULL) {
|
|
|
|
dom->log(rust_log::COMM, "invalid port, transmission incomplete");
|
|
|
|
return ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (buffer.is_empty()) {
|
|
|
|
dom->log(rust_log::COMM, "buffer is empty, transmission incomplete");
|
|
|
|
return ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(port->task->blocked_on(port)) {
|
|
|
|
buffer.dequeue(port->task->rendezvous_ptr);
|
|
|
|
port->task->wakeup(port);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
2010-06-23 21:03:09 -07:00
|
|
|
}
|
2010-07-28 00:36:35 -07:00
|
|
|
|
|
|
|
//
|
|
|
|
// Local Variables:
|
|
|
|
// mode: C++
|
|
|
|
// fill-column: 78;
|
|
|
|
// indent-tabs-mode: nil
|
|
|
|
// c-basic-offset: 4
|
|
|
|
// buffer-file-coding-system: utf-8-unix
|
|
|
|
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
|
|
|
|
// End:
|
|
|
|
//
|