Reducing the chances for race conditions in join.
This commit is contained in:
@@ -115,7 +115,10 @@ static size_t const BUF_BYTES = 2048;
|
|||||||
private: \
|
private: \
|
||||||
intptr_t ref_count; \
|
intptr_t ref_count; \
|
||||||
public: \
|
public: \
|
||||||
void ref() { sync::increment(ref_count); } \
|
void ref() { \
|
||||||
|
intptr_t old = sync::increment(ref_count); \
|
||||||
|
assert(old > 0); \
|
||||||
|
} \
|
||||||
void deref() { if(0 == sync::decrement(ref_count)) { delete this; } }
|
void deref() { if(0 == sync::decrement(ref_count)) { delete this; } }
|
||||||
|
|
||||||
template <typename T> struct rc_base {
|
template <typename T> struct rc_base {
|
||||||
|
|||||||
@@ -160,7 +160,17 @@ rust_kernel::get_task_by_id(rust_task_id id) {
|
|||||||
rust_task *task = NULL;
|
rust_task *task = NULL;
|
||||||
// get leaves task unchanged if not found.
|
// get leaves task unchanged if not found.
|
||||||
task_table.get(id, &task);
|
task_table.get(id, &task);
|
||||||
if(task) task->ref();
|
if(task) {
|
||||||
|
if(task->get_ref_count() == 0) {
|
||||||
|
// this means the destructor is running, since the destructor
|
||||||
|
// grabs the kernel lock to unregister the task. Pretend this
|
||||||
|
// doesn't actually exist.
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
task->ref();
|
||||||
|
}
|
||||||
|
}
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -169,6 +169,10 @@ rust_task : public kernel_owned<rust_task>, rust_cond
|
|||||||
rust_port_id register_port(rust_port *port);
|
rust_port_id register_port(rust_port *port);
|
||||||
void release_port(rust_port_id id);
|
void release_port(rust_port_id id);
|
||||||
rust_port *get_port_by_id(rust_port_id id);
|
rust_port *get_port_by_id(rust_port_id id);
|
||||||
|
|
||||||
|
// Use this function sparingly. Depending on the ref count is generally
|
||||||
|
// not at all safe.
|
||||||
|
intptr_t get_ref_count() const { return ref_count; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -27,4 +27,4 @@ fn main(args: vec[str]) {
|
|||||||
task::_spawn(bind f(n));
|
task::_spawn(bind f(n));
|
||||||
i += 1u;
|
i += 1u;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user