Skip to content

Commit 5e05793

Browse files
ernestmamanguyenhuy
authored andcommitted
Rollout ASDeallocQueueV2 #trivial (TextureGroup#1143)
1 parent f656dbb commit 5e05793

File tree

3 files changed

+8
-176
lines changed

3 files changed

+8
-176
lines changed

Source/ASExperimentalFeatures.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,9 @@ typedef NS_OPTIONS(NSUInteger, ASExperimentalFeatures) {
2121
ASExperimentalUnfairLock = 1 << 3, // exp_unfair_lock
2222
ASExperimentalLayerDefaults = 1 << 4, // exp_infer_layer_defaults
2323
ASExperimentalNetworkImageQueue = 1 << 5, // exp_network_image_queue
24-
ASExperimentalDeallocQueue = 1 << 6, // exp_dealloc_queue_v2
25-
ASExperimentalCollectionTeardown = 1 << 7, // exp_collection_teardown
26-
ASExperimentalFramesetterCache = 1 << 8, // exp_framesetter_cache
27-
ASExperimentalSkipClearData = 1 << 9, // exp_skip_clear_data
24+
ASExperimentalCollectionTeardown = 1 << 6, // exp_collection_teardown
25+
ASExperimentalFramesetterCache = 1 << 7, // exp_framesetter_cache
26+
ASExperimentalSkipClearData = 1 << 8, // exp_skip_clear_data
2827
ASExperimentalFeatureAll = 0xFFFFFFFF
2928
};
3029

Source/ASRunLoopQueue.mm

Lines changed: 5 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -31,177 +31,21 @@ static void runLoopSourceCallback(void *info) {
3131

3232
#pragma mark - ASDeallocQueue
3333

34-
@interface ASDeallocQueueV1 : ASDeallocQueue
35-
@end
36-
@interface ASDeallocQueueV2 : ASDeallocQueue
37-
@end
38-
39-
@implementation ASDeallocQueue
34+
@implementation ASDeallocQueue {
35+
std::vector<CFTypeRef> _queue;
36+
ASDN::Mutex _lock;
37+
}
4038

4139
+ (ASDeallocQueue *)sharedDeallocationQueue NS_RETURNS_RETAINED
4240
{
4341
static ASDeallocQueue *deallocQueue = nil;
4442
static dispatch_once_t onceToken;
4543
dispatch_once(&onceToken, ^{
46-
if (ASActivateExperimentalFeature(ASExperimentalDeallocQueue)) {
47-
deallocQueue = [[ASDeallocQueueV2 alloc] init];
48-
} else {
49-
deallocQueue = [[ASDeallocQueueV1 alloc] init];
50-
}
44+
deallocQueue = [[ASDeallocQueue alloc] init];
5145
});
5246
return deallocQueue;
5347
}
5448

55-
- (void)releaseObjectInBackground:(id _Nullable __strong *)objectPtr
56-
{
57-
ASDisplayNodeFailAssert(@"Abstract method.");
58-
}
59-
60-
- (void)drain
61-
{
62-
ASDisplayNodeFailAssert(@"Abstract method.");
63-
}
64-
65-
@end
66-
67-
@implementation ASDeallocQueueV1 {
68-
NSThread *_thread;
69-
NSCondition *_condition;
70-
std::deque<id> _queue;
71-
ASDN::RecursiveMutex _queueLock;
72-
}
73-
74-
- (void)releaseObjectInBackground:(id _Nullable __strong *)objectPtr
75-
{
76-
if (objectPtr != NULL && *objectPtr != nil) {
77-
ASDN::MutexLocker l(_queueLock);
78-
_queue.push_back(*objectPtr);
79-
*objectPtr = nil;
80-
}
81-
}
82-
83-
- (void)threadMain
84-
{
85-
@autoreleasepool {
86-
__unsafe_unretained __typeof__(self) weakSelf = self;
87-
// 100ms timer. No resources are wasted in between, as the thread sleeps, and each check is fast.
88-
// This time is fast enough for most use cases without excessive churn.
89-
CFRunLoopTimerRef timer = CFRunLoopTimerCreateWithHandler(NULL, -1, 0.1, 0, 0, ^(CFRunLoopTimerRef timer) {
90-
weakSelf->_queueLock.lock();
91-
if (weakSelf->_queue.size() == 0) {
92-
weakSelf->_queueLock.unlock();
93-
return;
94-
}
95-
// The scope below is entered while already locked. @autorelease is crucial here; see PR 2890.
96-
__unused NSInteger count; // Prevent static analyzer warning if release build
97-
@autoreleasepool {
98-
#if ASRunLoopQueueLoggingEnabled
99-
NSLog(@"ASDeallocQueue Processing: %lu objects destroyed", weakSelf->_queue.size());
100-
#endif
101-
// Sometimes we release 10,000 objects at a time. Don't hold the lock while releasing.
102-
std::deque<id> currentQueue = weakSelf->_queue;
103-
count = currentQueue.size();
104-
ASSignpostStartCustom(ASSignpostDeallocQueueDrain, self, count);
105-
weakSelf->_queue = std::deque<id>();
106-
weakSelf->_queueLock.unlock();
107-
currentQueue.clear();
108-
}
109-
ASSignpostEndCustom(ASSignpostDeallocQueueDrain, self, count, ASSignpostColorDefault);
110-
});
111-
112-
CFRunLoopRef runloop = CFRunLoopGetCurrent();
113-
CFRunLoopAddTimer(runloop, timer, kCFRunLoopCommonModes);
114-
115-
[_condition lock];
116-
[_condition signal];
117-
// At this moment, -init is signalled that the thread is guaranteed to be finished starting.
118-
[_condition unlock];
119-
120-
// Keep processing events until the runloop is stopped.
121-
CFRunLoopRun();
122-
123-
CFRunLoopTimerInvalidate(timer);
124-
CFRunLoopRemoveTimer(runloop, timer, kCFRunLoopCommonModes);
125-
CFRelease(timer);
126-
127-
[_condition lock];
128-
[_condition signal];
129-
// At this moment, -stop is signalled that the thread is guaranteed to be finished exiting.
130-
[_condition unlock];
131-
}
132-
}
133-
134-
- (instancetype)init
135-
{
136-
if ((self = [super init])) {
137-
_condition = [[NSCondition alloc] init];
138-
139-
_thread = [[NSThread alloc] initWithTarget:self selector:@selector(threadMain) object:nil];
140-
_thread.name = @"ASDeallocQueue";
141-
142-
// Use condition to ensure NSThread has finished starting.
143-
[_condition lock];
144-
[_thread start];
145-
[_condition wait];
146-
[_condition unlock];
147-
}
148-
return self;
149-
}
150-
151-
- (void)stop
152-
{
153-
if (!_thread) {
154-
return;
155-
}
156-
157-
[_condition lock];
158-
[self performSelector:@selector(_stop) onThread:_thread withObject:nil waitUntilDone:NO];
159-
[_condition wait];
160-
// At this moment, the thread is guaranteed to be finished running.
161-
[_condition unlock];
162-
_thread = nil;
163-
}
164-
165-
- (void)drain
166-
{
167-
[self performSelector:@selector(_drain) onThread:_thread withObject:nil waitUntilDone:YES];
168-
}
169-
170-
- (void)_drain
171-
{
172-
while (true) {
173-
@autoreleasepool {
174-
_queueLock.lock();
175-
std::deque<id> currentQueue = _queue;
176-
_queue = std::deque<id>();
177-
_queueLock.unlock();
178-
179-
if (currentQueue.empty()) {
180-
return;
181-
} else {
182-
currentQueue.clear();
183-
}
184-
}
185-
}
186-
}
187-
188-
- (void)_stop
189-
{
190-
CFRunLoopStop(CFRunLoopGetCurrent());
191-
}
192-
193-
- (void)dealloc
194-
{
195-
[self stop];
196-
}
197-
198-
@end
199-
200-
@implementation ASDeallocQueueV2 {
201-
std::vector<CFTypeRef> _queue;
202-
ASDN::Mutex _lock;
203-
}
204-
20549
- (void)dealloc
20650
{
20751
ASDisplayNodeFailAssert(@"Singleton should not dealloc.");

examples/CatDealsCollectionView/Sample/AppDelegate.m

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,3 @@ - (void)pushNewViewController
4747
}
4848

4949
@end
50-
51-
@implementation ASConfiguration (UserProvided)
52-
53-
+ (ASConfiguration *)textureConfiguration
54-
{
55-
ASConfiguration *cfg = [[ASConfiguration alloc] init];
56-
cfg.experimentalFeatures = ASExperimentalDeallocQueue;
57-
return cfg;
58-
}
59-
60-
@end

0 commit comments

Comments
 (0)