Chromium Code Reviews| Index: ios/net/crn_http_protocol_handler_pauseable_proxy.mm |
| diff --git a/ios/net/crn_http_protocol_handler_pauseable_proxy.mm b/ios/net/crn_http_protocol_handler_pauseable_proxy.mm |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..51486ec347f8afcc950f6454bd296d38d00a0855 |
| --- /dev/null |
| +++ b/ios/net/crn_http_protocol_handler_pauseable_proxy.mm |
| @@ -0,0 +1,95 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#import "ios/net/crn_http_protocol_handler_pauseable_proxy.h" |
| + |
| +@interface CRNHTTPProtocolHandlerProxyWithClientThread () {} |
| + |
| +- (void)performSelectorOnClientThread:(SEL)aSelector withObject:(id)arg; |
| + |
| +@end |
| + |
| +// The |QueuedSelector| class represents a single queued callback, with the |
|
marq (ping after 24h)
2015/05/22 16:56:53
Just use NSInvocation to instead of a custom class
Elly Fong-Jones
2015/05/26 21:16:09
Done.
|
| +// selector to be performed and the object on which to perform it. |
| +@interface QueuedSelector : NSObject { |
| + SEL _selector; |
| + id _object; |
| +} |
| + |
| +- (id)initWithSelector:(SEL)selector |
| + withObject:(id)object; |
| +- (SEL)selector; |
| +- (id)object; |
| + |
| +@end |
| + |
| +@implementation QueuedSelector |
| + |
| +- (id)initWithSelector:(SEL)selector |
| + withObject:(id)object { |
| + if ((self = [super init])) { |
| + _selector = selector; |
| + _object = object; |
| + } |
| + return self; |
| +} |
| + |
| +- (SEL)selector { |
| + return _selector; |
| +} |
| + |
| +- (id)object { |
| + return _object; |
| +} |
| + |
| +@end |
| + |
| +@interface CRNHTTPProtocolHandlerPauseableProxy () { |
| + BOOL _paused; |
| + NSMutableArray* _queuedSelectors; |
| +} |
| + |
| +@end |
| + |
| +@implementation CRNHTTPProtocolHandlerPauseableProxy |
| + |
| +- (instancetype)initWithProtocol:(NSURLProtocol*)protocol |
| + clientThread:(NSThread*)clientThread |
| + runLoopMode:(NSString*)mode { |
| + if ((self = [super initWithProtocol:protocol |
| + clientThread:clientThread |
| + runLoopMode:mode])) { |
| + _paused = NO; |
| + _queuedSelectors = [[NSMutableArray alloc] init]; |
| + } |
| + return self; |
| +} |
| + |
| +// Overridden from CRNHTTPProtocolHandlerProxyWithClientThread. If |_paused| is |
| +// YES, we queue the selector/object pair in |_queuedSelectors|; otherwise, we |
| +// invoke the given selector directly on the client thread. |
| +- (void)performSelectorOnClientThread:(SEL)aSelector withObject:(id)arg { |
| + if (!_paused) { |
| + [super performSelectorOnClientThread:aSelector withObject:arg]; |
| + } else { |
| + QueuedSelector* qs = [[QueuedSelector alloc] |
| + initWithSelector:aSelector |
| + withObject:arg]; |
|
marq (ping after 24h)
2015/05/22 16:56:53
(This is a memory leak, BTW).
|
| + [_queuedSelectors addObject:qs]; |
|
marq (ping after 24h)
2015/05/22 16:56:53
Try this:
scoped_nsobject<NSInvocation> qs([[NSIn
|
| + } |
| +} |
| + |
| +- (void)pause { |
| + _paused = YES; |
| +} |
| + |
| +- (void)resume { |
| + _paused = NO; |
| + for (QueuedSelector* qs : _queuedSelectors) { |
|
marq (ping after 24h)
2015/05/22 16:56:53
for (NSInvocation* qs : _queuedSelectors) {
[sel
|
| + [self performSelectorOnClientThread:[qs selector] withObject:[qs object]]; |
|
marq (ping after 24h)
2015/05/22 16:56:53
What if [self pause] is a queued selector, or exec
|
| + } |
| + [_queuedSelectors removeAllObjects]; |
| +} |
| + |
| +@end |