-
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
Mark ASRunLoopQueue as drained if it contains only NULLs #558
Mark ASRunLoopQueue as drained if it contains only NULLs #558
Conversation
I finally covered |
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.
First of all, thanks for investigating the problem and submit this patch! Extra kudos for the new unit tests!
That being said, I have 1 small problem with the new _isQueueDrained
state, that is we need to do extra work to make sure it's up-to-date. If the problem lies within NSPointerArray
(and there is indeed a radar for it), maybe we should somehow force it to do the right thing? I think there are a couple of things we can do:
- Use
allObjects.count
instead ofcount
. Unlike the latter, the former API shouldn't includeNULL
pointers. - Whenever needed, force the pointer array to compact by inserting a
nil
pointer before callingcompact
, as suggested here.
Let me know what you think!
CHANGELOG.md
Outdated
@@ -20,6 +20,7 @@ | |||
- Fixed a memory corruption issue in the ASImageNode display system. [Adlai Holler](https://github.com/Adlai-Holler) [#555](https://github.com/TextureGroup/Texture/pull/555) | |||
- [Breaking] Rename ASCollectionGalleryLayoutSizeProviding to ASCollectionGalleryLayoutPropertiesProviding. Besides a fixed item size, it now can provide interitem and line spacings, as well as section inset [Huy Nguyen](https://github.com/nguyenhuy) [#496](https://github.com/TextureGroup/Texture/pull/496) [#533](https://github.com/TextureGroup/Texture/pull/533) | |||
- Deprecate `-[ASDisplayNode displayWillStart]` in favor of `-displayWillStartAsynchronously:` [Huy Nguyen](https://github.com/nguyenhuy) [536](https://github.com/TextureGroup/Texture/pull/536) | |||
- Mark ASRunLoopQueue as drained if it contains only NULLs [Cesar Estebanez](https://github.com/cesteban) |
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.
Nit: Please add the PR's URL.
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.
Yup, sorry!
Also, please update the license in |
@nguyenhuy Actually, my first implementation that passed the test was something similar to this: NSInteger foundItemCount = 0;
for (NSInteger i = 0; i < internalQueueCount && foundItemCount < maxCountToProcess; i++) {
//...
}
if (foundItemCount == 0) {
// If _internalQueue holds weak references, and all of them just become nil, then the array
// is never marked as needsCompletion, and compact will return early, not removing the nils.
// Inserting a nil here ensures the compaction will take place.
[_internalQueue addPointer:nil];
}
[_internalQueue compact];
if (_internalQueue.count == 0) {
isQueueDrained = YES;
} Do you prefer this kind of approach? I can recover it, just let me know. |
@cesteban Yes, I think it's a cleaner approach. May worth adding the StackOverflow and OpenRadar links. |
…aining a state for _isQueueDrained
Thanks @nguyenhuy. There we go! |
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.
Great win! Thank you!
…p#558) * Mark ASRunLoopQueue as drained if it contains only NULLs * Update CHANGELOG.md * Cover ASRunLoopQueue with tests * Include PR link in CHANGELOG.md * Replace license header of ASRunLoopQueueTests.m with correct one * Insert a nil in _internalQueue to ensure compaction, instead of maintaining a state for _isQueueDrained
I wrote a failing tests for #518. Then made it pass.
Apparently, the problem is
NSPointerArray
won't be marked asneedsCompaction
when stored weak pointers become NULL. This makes subsequent calls tocompact
to return early without effectively removing NULL's. As a resultASRunLoopQueue
is never marked as drained, event though there is no more work to do.I added an
isEmpty
public property toASRunLoopQueue
which is only used in tests. That's not pretty, but I went this way because IMO the property makes sense in an API like that (if you have a queue, it's very natural to have a way to know if it's empty). If you don't want to have this property, we need to find out another way for the test to sense that the queue has been marked as drained.Finally, I believe
ASRunLoopQueue
should have a lot more tests, given the importance of the component. I would try to find the time to write a bunch of them, but that should be a different branch IMO.Please, let me know your thoughts.
Edit (huy): Closes #518.