aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/objective-c/GRPCClient
diff options
context:
space:
mode:
authorGravatar Muxi Yan <mxyan@google.com>2018-10-22 18:25:16 -0700
committerGravatar Muxi Yan <mxyan@google.com>2018-10-22 18:25:16 -0700
commite13c8678264d85353bb2ce49ae829c03f6c9493f (patch)
tree8b09b21775c64fc4888fdda395e8792d43a236e6 /src/objective-c/GRPCClient
parent3566540f16451ea87aff980b5de13c41a8debeb6 (diff)
Do not issue more message when the call is canceled
Diffstat (limited to 'src/objective-c/GRPCClient')
-rw-r--r--src/objective-c/GRPCClient/GRPCCall.m61
1 files changed, 45 insertions, 16 deletions
diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m
index 7e0640e8ae..23c8d0f2d7 100644
--- a/src/objective-c/GRPCClient/GRPCCall.m
+++ b/src/objective-c/GRPCClient/GRPCCall.m
@@ -104,6 +104,11 @@ const char *kCFStreamVarName = "grpc_cfstream";
dispatch_queue_t _dispatchQueue;
/** Flags whether call has started. */
BOOL _started;
+ /**
+ * Flags that the call has been canceled. When this is true, pending initial metadata and message
+ * should not be issued to \a _handler. This ivar must be accessed with lock to self.
+ */
+ BOOL _canceled;
}
- (instancetype)initWithRequestOptions:(GRPCRequestOptions *)requestOptions
@@ -135,6 +140,7 @@ const char *kCFStreamVarName = "grpc_cfstream";
}
dispatch_set_target_queue(responseHandler.dispatchQueue, _dispatchQueue);
_started = NO;
+ _canceled = NO;
}
return self;
@@ -217,6 +223,9 @@ const char *kCFStreamVarName = "grpc_cfstream";
self->_pipe = nil;
}
if (self->_handler) {
+ @synchronized(self) {
+ self->_canceled = YES;
+ }
id<GRPCResponseHandler> handler = self->_handler;
dispatch_async(handler.dispatchQueue, ^{
if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) {
@@ -252,30 +261,50 @@ const char *kCFStreamVarName = "grpc_cfstream";
}
- (void)issueInitialMetadata:(NSDictionary *)initialMetadata {
- id<GRPCResponseHandler> handler = _handler;
- if ([handler respondsToSelector:@selector(receivedInitialMetadata:)]) {
- dispatch_async(handler.dispatchQueue, ^{
- [handler receivedInitialMetadata:initialMetadata];
- });
+ if (_handler != nil && initialMetadata != nil) {
+ id<GRPCResponseHandler> handler = _handler;
+ if ([handler respondsToSelector:@selector(receivedInitialMetadata:)]) {
+ dispatch_async(handler.dispatchQueue, ^{
+ // Do not issue initial metadata if the call is already canceled.
+ __block BOOL canceled = NO;
+ @synchronized(self) {
+ canceled = self->_canceled;
+ }
+ if (!canceled) {
+ [handler receivedInitialMetadata:initialMetadata];
+ }
+ });
+ }
}
}
- (void)issueMessage:(id)message {
- id<GRPCResponseHandler> handler = _handler;
- if ([handler respondsToSelector:@selector(receivedRawMessage:)]) {
- dispatch_async(handler.dispatchQueue, ^{
- [handler receivedRawMessage:message];
- });
+ if (_handler != nil && message != nil) {
+ id<GRPCResponseHandler> handler = _handler;
+ if ([handler respondsToSelector:@selector(receivedRawMessage:)]) {
+ dispatch_async(handler.dispatchQueue, ^{
+ // Do not issue message if the call is already canceled.
+ __block BOOL canceled = NO;
+ @synchronized(self) {
+ canceled = self->_canceled;
+ }
+ if (!canceled) {
+ [handler receivedRawMessage:message];
+ }
+ });
+ }
}
}
- (void)issueClosedWithTrailingMetadata:(NSDictionary *)trailingMetadata error:(NSError *)error {
- id<GRPCResponseHandler> handler = _handler;
- NSDictionary *trailers = _call.responseTrailers;
- if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) {
- dispatch_async(handler.dispatchQueue, ^{
- [handler closedWithTrailingMetadata:trailers error:error];
- });
+ if (_handler != nil) {
+ id<GRPCResponseHandler> handler = _handler;
+ NSDictionary *trailers = _call.responseTrailers;
+ if ([handler respondsToSelector:@selector(closedWithTrailingMetadata:error:)]) {
+ dispatch_async(handler.dispatchQueue, ^{
+ [handler closedWithTrailingMetadata:trailers error:error];
+ });
+ }
}
}