From 702243698cf6f56750426ca252e24951f46a5d4c Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Mon, 21 Mar 2016 22:19:43 +0100 Subject: [PATCH 1/2] For GRPCOperation's, ensure finish _handler can only be called once, and release it when called, so weak ptrs needn't be used with it, and the call won't be released until the finish handler is called. When the connectivityMonitor determines the connection has been lost, pull the host disconnect call. Creates an unreliable connection when connectivity is restored. Calling finishWithError: is sufficient. --- src/objective-c/GRPCClient/GRPCCall.m | 46 ++++++++----------- .../GRPCClient/private/GRPCWrappedCall.m | 4 +- 2 files changed, 22 insertions(+), 28 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 2d45818b6e9..1847d6016ff 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -308,37 +308,30 @@ NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey"; } - (void)invokeCall { - __weak GRPCCall *weakSelf = self; [self invokeCallWithHeadersHandler:^(NSDictionary *headers) { // Response headers received. - GRPCCall *strongSelf = weakSelf; - if (strongSelf) { - strongSelf.responseHeaders = headers; - [strongSelf startNextRead]; - } + self.responseHeaders = headers; + [self startNextRead]; } completionHandler:^(NSError *error, NSDictionary *trailers) { - GRPCCall *strongSelf = weakSelf; - if (strongSelf) { - strongSelf.responseTrailers = trailers; - - if (error) { - NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; - if (error.userInfo) { - [userInfo addEntriesFromDictionary:error.userInfo]; - } - userInfo[kGRPCTrailersKey] = strongSelf.responseTrailers; - // TODO(jcanizales): The C gRPC library doesn't guarantee that the headers block will be - // called before this one, so an error might end up with trailers but no headers. We - // shouldn't call finishWithError until ater both blocks are called. It is also when this is - // done that we can provide a merged view of response headers and trailers in a thread-safe - // way. - if (strongSelf.responseHeaders) { - userInfo[kGRPCHeadersKey] = strongSelf.responseHeaders; - } - error = [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo]; + self.responseTrailers = trailers; + + if (error) { + NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; + if (error.userInfo) { + [userInfo addEntriesFromDictionary:error.userInfo]; + } + userInfo[kGRPCTrailersKey] = self.responseTrailers; + // TODO(jcanizales): The C gRPC library doesn't guarantee that the headers block will be + // called before this one, so an error might end up with trailers but no headers. We + // shouldn't call finishWithError until ater both blocks are called. It is also when this is + // done that we can provide a merged view of response headers and trailers in a thread-safe + // way. + if (self.responseHeaders) { + userInfo[kGRPCHeadersKey] = self.responseHeaders; } - [strongSelf finishWithError:error]; + error = [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo]; } + [self finishWithError:error]; }]; // Now that the RPC has been initiated, request writes can start. @synchronized(_requestWriter) { @@ -377,7 +370,6 @@ NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey"; [strongSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain code:GRPCErrorCodeUnavailable userInfo:@{NSLocalizedDescriptionKey: @"Connectivity lost."}]]; - [[GRPCHost hostWithAddress:strongSelf->_host] disconnect]; } }]; } diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index fe3d51da53a..16e5bff7ff7 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -54,7 +54,9 @@ - (void)finish { if (_handler) { - _handler(); + void(^handler)() = _handler; + _handler = nil; + handler(); } } @end From 6bda8497b889f1ca587006bf58bedca16296f72b Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Mon, 21 Mar 2016 23:15:09 +0100 Subject: [PATCH 2/2] Fixing copyrights. --- src/objective-c/GRPCClient/GRPCCall.m | 2 +- src/objective-c/GRPCClient/private/GRPCWrappedCall.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index 1847d6016ff..51263b073ca 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m index 16e5bff7ff7..f6527e283cf 100644 --- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m +++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without