Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(288)

Unified Diff: ios/net/crn_http_protocol_handler.mm

Issue 2632643003: Revert of Remove obsolete PauseableHttpProtocolHandler class. (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ios/net/crn_http_protocol_handler.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ios/net/crn_http_protocol_handler.mm
diff --git a/ios/net/crn_http_protocol_handler.mm b/ios/net/crn_http_protocol_handler.mm
index d2855b4e2aebe73594100d0c81cdb470557ab22d..bb9ac3b279565d8253a5c71e5f389356d34f57f7 100644
--- a/ios/net/crn_http_protocol_handler.mm
+++ b/ios/net/crn_http_protocol_handler.mm
@@ -1030,3 +1030,77 @@
}
@end
+
+#pragma mark -
+#pragma mark PauseableHttpProtocolHandler
+
+// The HttpProtocolHandler is called by the iOS system to handle the
+// NSURLRequest. This HttpProtocolHandler conforms to the observed semantics of
+// NSURLProtocol when used with NSURLSession on iOS 8 - i.e., |-startLoading|
+// means "start or resume request" and |-stopLoading| means "pause request".
+// Since there is no way to actually pause a request in the network stack, this
+// is implemented using a subclass of CRNHTTPProtocolHandlerProxy that knows how
+// to defer callbacks.
+//
+// Note that this class conforms to somewhat complex threading rules:
+// 1) |initWithRequest:cachedResponse:client:| and |dealloc| can be called on
+// any thread.
+// 2) |startLoading| and |stopLoading| are always called on the client thread.
+// 3) |stopLoading| is called before |dealloc| is called.
+//
+// The main wrinkle is that |dealloc|, which may be called on any thread, needs
+// to clean up a running network request. To do this, |dealloc| needs to run
+// |cancelRequest|, which needs to be run on the client thread. Since it is
+// guaranteed that |startLoading| is called before |dealloc| is called, the
+// |startLoading| method stores a pointer to the client thread, then |dealloc|
+// asks that client thread to perform the |cancelRequest| selector via
+// |scheduleCancelRequest|.
+//
+// Some of the above logic is implemented in the parent class
+// (CRNHTTPProtocolHandler) because it is convenient.
+@implementation CRNPauseableHTTPProtocolHandler {
+ BOOL _started;
+ dispatch_queue_t _queue;
+}
+
+#pragma mark NSURLProtocol methods
+
+- (void)dealloc {
+ [self scheduleCancelRequest];
+}
+
+#pragma mark NSURLProtocol overrides.
+
+- (void)startLoading {
+ if (_started) {
+ [[self getProtocolHandlerProxy] resume];
+ return;
+ }
+
+ _started = YES;
+ [super startLoading];
+}
+
+- (void)stopLoading {
+ [[self getProtocolHandlerProxy] pause];
+}
+
+// This method has unusual concurrency properties. It can be called on any
+// thread, but it must be called from |-dealloc|, which guarantees that no other
+// method of this object is running concurrently (since |-dealloc| is only
+// called when the last reference to the object drops).
+//
+// This method takes a reference to _core to ensure that _core lives long enough
+// to have the request cleanly cancelled.
+- (void)scheduleCancelRequest {
+ DeferredCancellation* cancellation =
+ [[DeferredCancellation alloc] initWithCore:[self getCore]];
+ NSArray* modes = @[ [[NSRunLoop currentRunLoop] currentMode] ];
+ [cancellation performSelector:@selector(cancel)
+ onThread:[self getClientThread]
+ withObject:nil
+ waitUntilDone:NO
+ modes:modes];
+}
+
+@end
« no previous file with comments | « ios/net/crn_http_protocol_handler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698