diff options
Diffstat (limited to 'Foundation/GTMTransientRootProxy.m')
-rw-r--r-- | Foundation/GTMTransientRootProxy.m | 230 |
1 files changed, 0 insertions, 230 deletions
diff --git a/Foundation/GTMTransientRootProxy.m b/Foundation/GTMTransientRootProxy.m deleted file mode 100644 index 2f7dfec..0000000 --- a/Foundation/GTMTransientRootProxy.m +++ /dev/null @@ -1,230 +0,0 @@ -// -// GTMTransientRootProxy.m -// -// Copyright 2006-2009 Google Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); you may not -// use this file except in compliance with the License. You may obtain a copy -// of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// License for the specific language governing permissions and limitations under -// the License. -// - -#import "GTMTransientRootProxy.h" -#import "GTMObjC2Runtime.h" - -// Private methods on NSMethodSignature that we need to call. This method has -// been available since 10.0, but Apple didn't add it to the headers until 10.5 -#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 -@interface NSMethodSignature (UndeclaredMethods) -+ (NSMethodSignature *)signatureWithObjCTypes:(const char *)types; -@end -#endif // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 - -@interface GTMTransientRootProxy (PrivateMethods) -// Returns an NSConnection for NSMacPorts. This method is broken out to allow -// subclasses to override it to generate different types of NSConnections. -- (NSConnection *)makeConnection; - -// Returns the "real" proxy (stored in the realProxy_ ivar) associated with this -// instance. If realProxy_ is nil, then an attempt is made to make a connection -// to create the realProxy_. -// -- (NSDistantObject *)realProxy; - -// "Releases" the realProxy_ ivar, and removes |self| as an observer from -// the NSNotificationCenter. -// -- (void)releaseRealProxy; - -// Notification that a connection has died. -- (void)connectionDidDie:(NSNotification *)notification; -@end - -@implementation GTMTransientRootProxy - -+ (id)rootProxyWithRegisteredName:(NSString *)name - host:(NSString *)host - protocol:(Protocol *)protocol - requestTimeout:(NSTimeInterval)requestTimeout - replyTimeout:(NSTimeInterval)replyTimeout { - return [[[self alloc] initWithRegisteredName:name - host:host - protocol:protocol - requestTimeout:requestTimeout - replyTimeout:replyTimeout] autorelease]; -} - -- (id)initWithRegisteredName:(NSString *)name - host:(NSString *)host - protocol:(Protocol *)protocol - requestTimeout:(NSTimeInterval)requestTimeout - replyTimeout:(NSTimeInterval)replyTimeout { - if (!name || !protocol) { - [self release]; - return nil; - } - - requestTimeout_ = requestTimeout; - replyTimeout_ = replyTimeout; - - registeredName_ = [name copy]; - host_ = [host copy]; - - protocol_ = protocol; // Protocols can't be retained - - return self; -} - -- (id)init { - return [self initWithRegisteredName:nil - host:nil - protocol:nil - requestTimeout:0.0 - replyTimeout:0.0]; -} - -- (void)dealloc { - [self releaseRealProxy]; - [registeredName_ release]; - [host_ release]; - [super dealloc]; -} - -- (BOOL)isConnected { - BOOL result = NO; - @synchronized (self) { - result = [[[self realProxy] connectionForProxy] isValid]; - } - return result; -} - -- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { - struct objc_method_description mdesc; - mdesc = protocol_getMethodDescription(protocol_, selector, YES, YES); - NSMethodSignature *returnValue = nil; - if (mdesc.types == NULL) { - // COV_NF_START - _GTMDevLog(@"Unable to get the protocol method description. Returning " - @"nil."); - // COV_NF_END - } else { - returnValue = [NSMethodSignature signatureWithObjCTypes:mdesc.types]; - } - return returnValue; -} - -- (void)forwardInvocation:(NSInvocation *)invocation { - @try { - NSDistantObject *target = [self realProxy]; - [invocation invokeWithTarget:target]; - - // We need to catch NSException* here rather than "id" because we need to - // treat |ex| as an NSException when using the -name method. Also, we're - // only looking to catch a few types of exception here, all of which are - // NSException types; the rest we just rethrow. - } @catch (NSException *ex) { - NSString *exName = [ex name]; - // If we catch an exception who's name matches any of the following types, - // it's because the DO connection probably went down. So, we'll just - // release our realProxy_, and attempt to reconnect on the next call. - if ([exName isEqualToString:NSPortTimeoutException] - || [exName isEqualToString:NSInvalidSendPortException] - || [exName isEqualToString:NSInvalidReceivePortException] - || [exName isEqualToString:NSFailedAuthenticationException] - || [exName isEqualToString:NSPortSendException] - || [exName isEqualToString:NSPortReceiveException]) { - [self releaseRealProxy]; // COV_NF_LINE - } else { - // If the exception was any other type (commonly - // NSInvalidArgumentException) then we'll just re-throw it to the caller. - @throw; - } - } // COV_NF_LINE -} - -@end - -@implementation GTMTransientRootProxy (PrivateMethods) - -- (NSConnection *)makeConnection { - return [NSConnection connectionWithRegisteredName:registeredName_ host:host_]; -} - -- (NSDistantObject *)realProxy { - NSDistantObject *returnProxy = nil; - - @synchronized (self) { - // No change so no notification - if (realProxy_) return realProxy_; - - NSConnection *conn = [self makeConnection]; - [conn setRequestTimeout:requestTimeout_]; - [conn setReplyTimeout:replyTimeout_]; - @try { - // Try to get the root proxy for this connection's vended object. - realProxy_ = [conn rootProxy]; - } @catch (id ex) { - // We may fail here if we can't get the root proxy in the amount of time - // specified by the timeout above. This may happen, for example, if the - // server process is stopped (via SIGSTOP). We'll just ignore this, and - // try again at the next message. - [conn invalidate]; - return nil; - } - if (!realProxy_) { - [conn invalidate]; - // Again, no change in connection status - return nil; - } - [realProxy_ retain]; - [realProxy_ setProtocolForProxy:protocol_]; - NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - [nc addObserver:self - selector:@selector(connectionDidDie:) - name:NSConnectionDidDieNotification - object:conn]; - // Retain/autorelease so it lives at least the duration of this synchronize - returnProxy = [[realProxy_ retain] autorelease]; - } // @synchronized (self) - - return returnProxy; -} - -- (void)connectionDidDie:(NSNotification *)notification { - [self releaseRealProxy]; -} - -- (void)releaseRealProxy { - @synchronized (self) { - [[NSNotificationCenter defaultCenter] removeObserver:self]; - // Only trigger if we had a proxy before - if (realProxy_) { - [realProxy_ release]; - realProxy_ = nil; - } - } -} - -@end - -@implementation GTMRootProxyCatchAll - -- (void)forwardInvocation:(NSInvocation *)invocation { - @try { - [super forwardInvocation:invocation]; - } - @catch (id ex) { - // Log for developers, but basically ignore it. - _GTMDevLog(@"Proxy for invoking %@ has caught and is ignoring exception: %@", - NSStringFromSelector([invocation selector]), ex); - } -} - -@end |