Reintroduce linked failure (rust_port locking)
This reverts commit a10f52c5793b358a16e3e98db4b16c65ba8e254b.
This commit is contained in:
parent
aad184cc57
commit
62575d9c4a
@ -26,9 +26,11 @@ void rust_port::deref() {
|
|||||||
scoped_lock with(ref_lock);
|
scoped_lock with(ref_lock);
|
||||||
ref_count--;
|
ref_count--;
|
||||||
if (!ref_count) {
|
if (!ref_count) {
|
||||||
|
// The port owner is waiting for the port to be detached (if it
|
||||||
|
// hasn't already been killed)
|
||||||
|
scoped_lock with(task->lifecycle_lock);
|
||||||
if (task->blocked_on(&detach_cond)) {
|
if (task->blocked_on(&detach_cond)) {
|
||||||
// The port owner is waiting for the port to be detached
|
task->wakeup_inner(&detach_cond);
|
||||||
task->wakeup(&detach_cond);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -64,12 +66,15 @@ void rust_port::send(void *sptr) {
|
|||||||
assert(!buffer.is_empty() &&
|
assert(!buffer.is_empty() &&
|
||||||
"rust_chan::transmit with nothing to send.");
|
"rust_chan::transmit with nothing to send.");
|
||||||
|
|
||||||
if (task->blocked_on(this)) {
|
{
|
||||||
KLOG(kernel, comm, "dequeued in rendezvous_ptr");
|
scoped_lock with(task->lifecycle_lock);
|
||||||
buffer.dequeue(task->rendezvous_ptr);
|
if (task->blocked_on(this)) {
|
||||||
task->rendezvous_ptr = 0;
|
KLOG(kernel, comm, "dequeued in rendezvous_ptr");
|
||||||
task->wakeup(this);
|
buffer.dequeue(task->rendezvous_ptr);
|
||||||
did_rendezvous = true;
|
task->rendezvous_ptr = 0;
|
||||||
|
task->wakeup_inner(this);
|
||||||
|
did_rendezvous = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,11 +83,8 @@ void rust_port::send(void *sptr) {
|
|||||||
// it may be waiting on a group of ports
|
// it may be waiting on a group of ports
|
||||||
|
|
||||||
rust_port_selector *port_selector = task->get_port_selector();
|
rust_port_selector *port_selector = task->get_port_selector();
|
||||||
// This check is not definitive. The port selector will take a lock
|
// The port selector will check if the task is blocked, not us.
|
||||||
// and check again whether the task is still blocked.
|
port_selector->msg_sent_on(this);
|
||||||
if (task->blocked_on(port_selector)) {
|
|
||||||
port_selector->msg_sent_on(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ rust_port_selector::msg_sent_on(rust_port *port) {
|
|||||||
|
|
||||||
// Prevent two ports from trying to wake up the task
|
// Prevent two ports from trying to wake up the task
|
||||||
// simultaneously
|
// simultaneously
|
||||||
scoped_lock with(rendezvous_lock);
|
scoped_lock with(task->lifecycle_lock);
|
||||||
|
|
||||||
if (task->blocked_on(this)) {
|
if (task->blocked_on(this)) {
|
||||||
for (size_t i = 0; i < n_ports; i++) {
|
for (size_t i = 0; i < n_ports; i++) {
|
||||||
@ -85,7 +85,7 @@ rust_port_selector::msg_sent_on(rust_port *port) {
|
|||||||
n_ports = 0;
|
n_ports = 0;
|
||||||
*task->rendezvous_ptr = (uintptr_t) port;
|
*task->rendezvous_ptr = (uintptr_t) port;
|
||||||
task->rendezvous_ptr = NULL;
|
task->rendezvous_ptr = NULL;
|
||||||
task->wakeup(this);
|
task->wakeup_inner(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ class rust_port_selector : public rust_cond {
|
|||||||
private:
|
private:
|
||||||
rust_port **ports;
|
rust_port **ports;
|
||||||
size_t n_ports;
|
size_t n_ports;
|
||||||
lock_and_signal rendezvous_lock;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
rust_port_selector();
|
rust_port_selector();
|
||||||
|
@ -243,7 +243,7 @@ rust_task::must_fail_from_being_killed_inner() {
|
|||||||
// Only run this on the rust stack
|
// Only run this on the rust stack
|
||||||
void
|
void
|
||||||
rust_task::yield(bool *killed) {
|
rust_task::yield(bool *killed) {
|
||||||
// FIXME (#2787): clean this up
|
// FIXME (#2875): clean this up
|
||||||
if (must_fail_from_being_killed()) {
|
if (must_fail_from_being_killed()) {
|
||||||
{
|
{
|
||||||
scoped_lock with(lifecycle_lock);
|
scoped_lock with(lifecycle_lock);
|
||||||
@ -346,12 +346,11 @@ void rust_task::assert_is_running()
|
|||||||
assert(state == task_state_running);
|
assert(state == task_state_running);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME (#2851, #2787): This is only used by rust_port/rust_port selector,
|
// FIXME (#2851) Remove this code when rust_port goes away?
|
||||||
// and is inherently racy. Get rid of it.
|
|
||||||
bool
|
bool
|
||||||
rust_task::blocked_on(rust_cond *on)
|
rust_task::blocked_on(rust_cond *on)
|
||||||
{
|
{
|
||||||
scoped_lock with(lifecycle_lock);
|
lifecycle_lock.must_have_lock();
|
||||||
return cond == on;
|
return cond == on;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,8 +226,11 @@ private:
|
|||||||
char const *file,
|
char const *file,
|
||||||
size_t line);
|
size_t line);
|
||||||
|
|
||||||
|
friend class rust_port;
|
||||||
|
friend class rust_port_selector;
|
||||||
bool block_inner(rust_cond *on, const char* name);
|
bool block_inner(rust_cond *on, const char* name);
|
||||||
void wakeup_inner(rust_cond *from);
|
void wakeup_inner(rust_cond *from);
|
||||||
|
bool blocked_on(rust_cond *cond);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -243,7 +246,6 @@ public:
|
|||||||
void *args);
|
void *args);
|
||||||
void start();
|
void start();
|
||||||
void assert_is_running();
|
void assert_is_running();
|
||||||
bool blocked_on(rust_cond *cond); // FIXME (#2851) Get rid of this.
|
|
||||||
|
|
||||||
void *malloc(size_t sz, const char *tag, type_desc *td=0);
|
void *malloc(size_t sz, const char *tag, type_desc *td=0);
|
||||||
void *realloc(void *data, size_t sz);
|
void *realloc(void *data, size_t sz);
|
||||||
@ -435,7 +437,7 @@ rust_task::call_on_rust_stack(void *args, void *fn_ptr) {
|
|||||||
|
|
||||||
bool had_reentered_rust_stack = reentered_rust_stack;
|
bool had_reentered_rust_stack = reentered_rust_stack;
|
||||||
{
|
{
|
||||||
// FIXME (#2787) This must be racy. Figure it out.
|
// FIXME (#2875) This must be racy. Figure it out.
|
||||||
scoped_lock with(lifecycle_lock);
|
scoped_lock with(lifecycle_lock);
|
||||||
reentered_rust_stack = true;
|
reentered_rust_stack = true;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user