diff options
author | Muxi Yan <mxyan@google.com> | 2018-12-05 22:52:12 -0800 |
---|---|---|
committer | Muxi Yan <mxyan@google.com> | 2018-12-05 22:52:12 -0800 |
commit | dfec57a9a9ebfbe92709498074eb184527ef599e (patch) | |
tree | 908c18db682d435c380cc7eda58c79205eac2215 /src/objective-c/GRPCClient/private/GRPCChannelPool.m | |
parent | 459da578db5ae9bd95f91be2888236c4870a7314 (diff) |
Channel pool polishments
Diffstat (limited to 'src/objective-c/GRPCClient/private/GRPCChannelPool.m')
-rw-r--r-- | src/objective-c/GRPCClient/private/GRPCChannelPool.m | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/src/objective-c/GRPCClient/private/GRPCChannelPool.m b/src/objective-c/GRPCClient/private/GRPCChannelPool.m index 488766c0ed..391022efd1 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannelPool.m +++ b/src/objective-c/GRPCClient/private/GRPCChannelPool.m @@ -57,7 +57,8 @@ static const NSTimeInterval kDefaultChannelDestroyDelay = 30; } - (void)dealloc { - if ([_wrappedCalls objectEnumerator].allObjects.count != 0) { + // Disconnect GRPCWrappedCall objects created but not yet removed + if (_wrappedCalls.allObjects.count != 0) { NSEnumerator *enumerator = [_wrappedCalls objectEnumerator]; GRPCWrappedCall *wrappedCall; while ((wrappedCall = [enumerator nextObject])) { @@ -111,13 +112,17 @@ callOptions:(GRPCCallOptions *)callOptions { return; } @synchronized(self) { - if ([_wrappedCalls objectEnumerator].allObjects.count == 0) { + // Detect if all objects weakly referenced in _wrappedCalls are (implicitly) removed. In such + // case the channel is no longer referenced by a grpc_call object and can be destroyed after + // a certain delay. + if (_wrappedCalls.allObjects.count == 0) { NSDate *now = [NSDate date]; + NSAssert(now != nil, @"Unable to create NSDate object 'now'."); _lastTimedDestroy = now; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)_destroyDelay * NSEC_PER_SEC), _timerQueue, ^{ @synchronized(self) { - if (self->_lastTimedDestroy == now) { + if (now != nil && self->_lastTimedDestroy == now) { self->_wrappedChannel = nil; self->_lastTimedDestroy = nil; } @@ -128,17 +133,15 @@ callOptions:(GRPCCallOptions *)callOptions { } - (void)disconnect { - NSHashTable<GRPCWrappedCall *> *copiedWrappedCalls = nil; + NSArray<GRPCWrappedCall *> *copiedWrappedCalls = nil; @synchronized(self) { if (_wrappedChannel != nil) { _wrappedChannel = nil; - copiedWrappedCalls = [_wrappedCalls copy]; + copiedWrappedCalls = _wrappedCalls.allObjects; [_wrappedCalls removeAllObjects]; } } - NSEnumerator *enumerator = [copiedWrappedCalls objectEnumerator]; - GRPCWrappedCall *wrappedCall; - while ((wrappedCall = [enumerator nextObject])) { + for (GRPCWrappedCall *wrappedCall in copiedWrappedCalls) { [wrappedCall channelDisconnected]; } } @@ -155,9 +158,9 @@ callOptions:(GRPCCallOptions *)callOptions { } if ((self = [super init])) { - _channelConfiguration = channelConfiguration; + _channelConfiguration = [channelConfiguration copy]; _destroyDelay = destroyDelay; - _wrappedCalls = [[NSHashTable alloc] initWithOptions:NSHashTableWeakMemory capacity:1]; + _wrappedCalls = [NSHashTable weakObjectsHashTable]; _wrappedChannel = nil; _lastTimedDestroy = nil; #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 @@ -187,7 +190,7 @@ callOptions:(GRPCCallOptions *)callOptions { @interface GRPCChannelPool () -- (instancetype)initInstance NS_DESIGNATED_INITIALIZER; +- (instancetype)initPrivate NS_DESIGNATED_INITIALIZER; @end @@ -198,13 +201,13 @@ callOptions:(GRPCCallOptions *)callOptions { + (instancetype)sharedInstance { dispatch_once(&gInitChannelPool, ^{ gChannelPool = - [[GRPCChannelPool alloc] initInstance]; + [[GRPCChannelPool alloc] initPrivate]; NSAssert(gChannelPool != nil, @"Cannot initialize global channel pool."); }); return gChannelPool; } -- (instancetype)initInstance { +- (instancetype)initPrivate { if ((self = [super init])) { _channelPool = [NSMutableDictionary dictionary]; @@ -242,15 +245,15 @@ callOptions:(GRPCCallOptions *)callOptions { } - (void)disconnectAllChannels { - NSDictionary *copiedPooledChannels; + NSArray<GRPCPooledChannel *> *copiedPooledChannels; @synchronized(self) { - copiedPooledChannels = [NSDictionary dictionaryWithDictionary:_channelPool]; + copiedPooledChannels = _channelPool.allValues; } // Disconnect pooled channels. - [copiedPooledChannels enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { - [obj disconnect]; - }]; + for (GRPCPooledChannel *pooledChannel in copiedPooledChannels) { + [pooledChannel disconnect]; + } } - (void)connectivityChange:(NSNotification *)note { @@ -262,7 +265,7 @@ callOptions:(GRPCCallOptions *)callOptions { @implementation GRPCChannelPool (Test) - (instancetype)initTestPool { - return [self initInstance]; + return [self initPrivate]; } @end |