diff --git a/Source/NSConnection.m b/Source/NSConnection.m index 4f3a62db3..211955baa 100644 --- a/Source/NSConnection.m +++ b/Source/NSConnection.m @@ -997,6 +997,10 @@ static NSLock *cached_proxies_gate = nil; { [self addRequestMode: [parent->_requestModes objectAtIndex: count]]; } + if (parent->_useKeepalive == YES) + { + [self _enableKeepalive]; + } } else { @@ -1013,6 +1017,7 @@ static NSLock *cached_proxies_gate = nil; _requestModes = [[NSMutableArray alloc] initWithCapacity: 2]; [self addRequestMode: NSDefaultRunLoopMode]; [self addRequestMode: NSConnectionReplyMode]; + _useKeepalive = NO; /* * If we have no parent, we must handle incoming packets on our @@ -2419,18 +2424,25 @@ static void retEncoder (DOContext *ctxt) } } +/** + */ - (void) _enableKeepalive { - if (_receivePort == _sendPort) - { - [NSException raise: NSGenericException format: @"Illegal operation"]; - } - _useKeepalive = YES; + _useKeepalive = YES; /* Set so that child connections will inherit. */ _lastKeepalive = 0; - [self enableMultipleThreads]; - [[NSNotificationCenter defaultCenter] addObserver: self - selector: @selector(_keepalive:) - name: @"GSHousekeeping" object: nil]; + if (_receivePort != _sendPort) + { + /* If this is not a listening connection, we actually enable the + * keepalive timing (usng the regular housekeeping notifications) + * and must also enable multiple thread support as the keepalive + * notification may arrive in a different thread from the one we + * are running in. + */ + [self enableMultipleThreads]; + [[NSNotificationCenter defaultCenter] addObserver: self + selector: @selector(_keepalive:) + name: @"GSHousekeeping" object: nil]; + } } static void callDecoder (DOContext *ctxt) diff --git a/Tools/gdnc.m b/Tools/gdnc.m index 79f9041b9..b01c310f6 100644 --- a/Tools/gdnc.m +++ b/Tools/gdnc.m @@ -442,6 +442,14 @@ ihandler(int sig) conn = [[NSConnection alloc] initWithReceivePort: port sendPort: nil]; [conn setRootObject: self]; + /* For ms-windows we need to enable keepalive on the connection so that + * we will find out if the remote end goes away. + */ + if ([conn respondsToSelector: @selector(_enableKeepalive)]) + { + [conn _enableKeepalive]; + } + if ([hostname length] == 0 || [[NSHost hostWithName: hostname] isEqual: [NSHost currentHost]] == YES) { @@ -608,13 +616,6 @@ ihandler(int sig) name: NSConnectionDidDieNotification object: newConn]; [newConn setDelegate: self]; - /* For ms-windows we need to enable keepalive on the connection so that - * we will find out if the remote end goes away. - */ - if ([newConn respondsToSelector: @selector(_enableKeepalive)]) - { - [newConn _enableKeepalive]; - } /* * Create a new map table entry for this connection with a value that * is a table (normally with a single entry) containing registered