-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Replace every use of the foreach macro with an iterator loop #2658
Conversation
This prevents a race condition with Qt5. A foreach loop makes a copy of its Qt container, increasing the reference count to the container's internal data. Qt5 often asserts isDetached(), which requires the reference count to be <= 1. This assertion fails when the foreach loop increases the reference count at exactly the wrong moment. Using an iterator loop prevents an unnecessary copy from being made and ensures this race condition isn't triggered.
@@ -134,7 +134,7 @@ int compressbands(float *absspec_buffer, float *compressedband, int num_old, int | |||
|
|||
ratio=(float)usefromold/(float)num_new; | |||
|
|||
// foreach new subband | |||
// for each new subband |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- // foreach new subband
+ // for each new subband
bahahaha
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wondered if anyone would spot that one 😁. I really wanted grep -r foreach
to be clean 😋
Added the Testing still welcome, though. This crash only happens under pretty specific circumstances, so the PR should be crash-free otherwise. |
Is it possible to iterate Qt containers using the "new" C+11 for loops? Example: for( NotePlayHandle const * cnph : nphv )
{
// Do stuff with cnph
} This would be more compact and also make the resulting code more understandable. Personally I don't really like tons of references to |
@michaelgregorius Does this means a compiler that supports C++ 11? Not sure everyone has one. |
@midi-pascal C++11 |
@grejppi Ok then. I was just not sure. I just want to be sure I will be able to continue to contribute to my beloved lmms 👍 |
@michaelgregorius A most sensible suggestion! After reading up on them, I think they should work fine. They will call Before I do all the grunt work again, though, I would like to confirm that this foreach removal fixes the assert crashes it's supposed to fix. @Umcaruje do you have time for another stress test? I'll see if I can compile LMMS using Qt5 and reproduce the crashes, too. Oh and @midi-pascal: it appears that C++11 |
@Umcaruje do you have time for another stress test?
Yeah, I'll do one when I get back from my german test, that's in about a
couple of hours.
|
@Umcaruje Awesome, best of luck with the test! |
Ok, so I stress tested it by moving the channels rapidly, it passed. I left it in the background playing, but so far so good, no crashes. |
👏 |
Ok, I left LMMS idle for a couple of hours and it didn't crash. Amazing job @Fastigium ! |
Ok, I removed a channel that was sending to another channel while playing and got a segfault: But this is a completely different crash, I'll see if I can reliably reproduce it on both master and your branch, and will post another issue. |
Well, I found a Qt5 specific bug, that can always be reproduced: #2667 That might help in unraveling it |
I finished the C++11 |
Closing because #2669 fixes things even better 😊 |
This prevents a race condition with Qt5. A foreach loop makes a copy of its
Qt container, increasing the reference count to the container's internal
data. Qt5 often asserts isDetached(), which requires the reference count to
be <= 1. This assertion fails when the foreach loop increases the reference
count at exactly the wrong moment. Using an iterator loop prevents an
unnecessary copy from being made and ensures this race condition isn't
triggered.