-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
borrowable_ptr, a threadsave callback solution #1713
base: 2.5
Are you sure you want to change the base?
Conversation
Could you explain what specific problem motivated you to start working on this? Does it solve a problem that came up in #1675? |
I am experience rar crashes when shutting down Mixxx.I was never able to reproduce it under gdb, so I have never reported a bug. One idea is that this is caused by explicit direct connections across threads. Qt does not prevent to call a callback from an already deleted object, if there is a race between the callback call from one thread and the delete call from an other thread. |
We use these direct connection for the engine thread COs |
I cannot use this currently, because of pending #1700 |
Can we come back to this in a few weeks after the 2.2 feature freeze? |
I like to have this included. |
Why? |
I actually waiting for a review of #1700 more urgently. Our control objects where becoming a bit messy, and I think it is a good idea to clean them up in small steps instead of one giant PR. |
I'm not questioning that we should clean the code, but I don't think < 2 weeks until a feature freeze is a good time to be focusing on it unless it fixes an important bug. |
@rryan Do you want to have a look here? |
@uklotzde do you have interest to wrap your head around this? I would like it to fix the a probably cause of the crash on close fix I experience some times. |
Honestly I still don't get the point by reading the code?? Couldn't this be implemented in a simpler and more comprehensible way? I'm not able to decide if this works correctly in all possible cases. My feeling is that we might try to cover a design flaw by mitigating it with just another half-baked and fairly complex solution. I noticed that the implementation has some technical flaws, e.g. the constructors are inconsistent and behave unexpectedly when invoked with a nullptr. I came to the conclusion that we should use asynchronous signal/slot messaging whenever possible. Why plain callbacks? Trying to work around Qt's foundation and patterns is one of the main problems in our code base. I'm just criticizing myself, because this is what I would've done when rewriting the multi-threaded analysis code now. But I won't rewrite it a second time in C++ ;) The global track cache is a slightly different story. It's also far too complex, but since track objects appear as shared mutable state everywhere we didn't have a choice without rewriting large parts of the application. |
Thank you for looking into it. This pointer was my idea for solving a crash on shut down when this https://github.com/mixxxdj/mixxx/blob/master/src/control/control.h#L164 object is deleted while an other thread is just about to call callback. I would love to use a Qt solution for it, but it has not. Direct connections have no safety net in QT and suffer basically the same issue. My idea was to use this pointer type to workaround this limitation, in an almost look free way. Do you have alternative ideas? Is there a chance to tun this into a simpler and more comprehensible solution? That would be great. |
Would you please include an example were this technique is applied? I need to see it in action. We need this anyway. Adding unused and untested code to the repository is discouraged ;) |
I have started to use the new pointer here: https://github.com/mixxxdj/mixxx/blob/master/src/control/control.h#L164 Many instances can be replaced by ControlProxyLt #1717 |
This PR is marked as stale because it has been open 90 days with no activity. |
6dd2c4e
to
9687d2f
Compare
I have implemented the original solution on top of std::shared_ptr please have a look. |
A wrapper class to protect pointers owned by another entity, allowing
safe access to the referenced object across threads. This prevents the
object from being deleted by its owner while other threads are executing
functions on the referenced object, implemented mostly lock-free, except during
reset(), if the object is still in use.
Use cases are:
threads in such cases.
Unlike
std::shared_ptr
, the object is not deleted when the lastborrowed_ptr
falls out of scope. Ownership and deletion are always managedby the original owner (via
borrowable_ptr
).If the
borrowable_ptr
falls out of scope while there are activeborrowed_ptr
instances, the thread is suspended until all
borrowed_ptr
instances are deletedand the reference count reaches zero.
Thread safety:
borrowable_ptr
.borrowed_ptr
instances become null before pointingto the new object.
Usage: