-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot share RBTree between multiple threads #47
Comments
This is currently not possible because |
What about something like an |
Sure that would be possible. However you'll need to wait for #46 to land since custom |
Hi. It looks like Generic Reference Types are now merged. Would it be possible to share some example on how to make intrusive-collections thread-safe? |
You need to create an |
I think I made it work. Please take a look here. Does it look correct? I'm not sure if it's ok to have two separate |
Ideally it should look like this: struct AtomicLink {
locked: AtomicBool,
next: Cell<Option<NonNull<AtomicLink>>>,
prev: Cell<Option<NonNull<AtomicLink>>>,
}
unsafe impl Sync for AtomicLink {} The key point is that the link is locked when it is inserted into the intrusive collection and unlocked when it is removed. When the lock is held, accessing However our current |
@Amanieu does it look correct now? unsafe impl LinkOps for AtomicLinkOps {
type LinkPtr = NonNull<AtomicLink>;
#[inline]
unsafe fn acquire_link(&mut self, ptr: Self::LinkPtr) -> bool {
let r = ptr.as_ref();
if r.locked.swap(true, Ordering::SeqCst) {
// already locked
return false;
}
assert!(!r.is_linked());
r.next.set(None);
true
}
#[inline]
unsafe fn release_link(&mut self, ptr: Self::LinkPtr) {
let r = ptr.as_ref();
r.next.set(UNLINKED_MARKER);
assert!(r.locked.swap(false, Ordering::SeqCst));
}
} |
|
|
You should use
I guess you can leave
No it's not required since the link state is tracked separately in |
Thanks. Updated the gist with your recommendations. Would you like the PR with AtomicLink implemented? |
Thanks but I don't think it is a good fit for the intrusive-collections crate. It is better for you to keep the implementation separate. |
Hello,
I'm trying to have multiple threads access a shared RBTree instance. Here's a small reproduction of the problem:
This fails to compile with:
This appears to be because
rbtree::Link
implementsSend
but notSync
. I tried to work around this by usingArc<Mutex<MyData>>
but then I got stuck on the implementation ofMyAdapter
: implementingget_link
requires you to acquire the lock but there's no way to ensure that the lock is held (and then released) while the link is mutated.I wonder if it's actually fine to implement
Sync
forrbtree::Link
. As far as I can tell every safe method that modifies aLink
requires a mutable reference to the tree first. I think it might require changing theis_linked
method to be unsafe though.Is there something I'm just missing to make this work?
The text was updated successfully, but these errors were encountered: