From ad6ff45e65068d2a8fff5e50705dc707e4c4f5ce Mon Sep 17 00:00:00 2001 From: CaS Date: Sun, 20 Nov 2005 11:17:42 +0000 Subject: [PATCH] Improve user experience with distributed notification center. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@22049 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 4 + Source/NSDistributedNotificationCenter.m | 168 +++++++++----------- Source/win32/NSMessagePortNameServerWin32.m | 2 +- 3 files changed, 84 insertions(+), 90 deletions(-) diff --git a/ChangeLog b/ChangeLog index bf6af3ae4..3047df31b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,10 @@ and tell the application to terminate cleanly (or raise an exception if the NSApplication class is not linked). Should allow ms-windows to get a mingw32-based GNUstep app to shut down cleanly. + * Source/NSDistributedNotificationCenter.m: Rewrite code for connecting + to and starting up daemon to ahndle the process more quickly and + smoothly. Only complain if we can't to connect to it even after + launching it and retrying the connection for five seconds. 2005-11-16 Richard Frith-Macdonald diff --git a/Source/NSDistributedNotificationCenter.m b/Source/NSDistributedNotificationCenter.m index 3785d9d7d..7e20695e2 100644 --- a/Source/NSDistributedNotificationCenter.m +++ b/Source/NSDistributedNotificationCenter.m @@ -40,6 +40,7 @@ #include "Foundation/NSUserDefaults.h" #include "Foundation/NSHost.h" #include "Foundation/NSPortNameServer.h" +#include "Foundation/NSDebug.h" #include "../Tools/gdnc.h" @@ -582,33 +583,27 @@ static NSDistributedNotificationCenter *netCenter = nil; NSString *host = nil; NSString *service = nil; NSString *description = nil; + NSString *alternate = nil; NSPortNameServer *ns = nil; + Protocol *p = @protocol(GDNCProtocol); + NSConnection *c; #ifdef __MINGW32__ - if (_type == NSLocalNotificationCenterType) + if (_type == NSLocalNotificationCenterType + && [[NSUserDefaults standardUserDefaults] + boolForKey: @"GSMailslot"] == NO) { - if ([[NSUserDefaults standardUserDefaults] - boolForKey: @"GSMailslot"] == YES) - { - host = @""; - ns = [NSMessagePortNameServer sharedInstance]; - service = GDNC_SERVICE; - description = @"local host"; - } - else - { - ASSIGN(_type, GSPublicNotificationCenterType); - } + ASSIGN(_type, GSPublicNotificationCenterType); } -#else +#endif + if (_type == NSLocalNotificationCenterType) { - host = @""; ns = [NSMessagePortNameServer sharedInstance]; + host = @""; service = GDNC_SERVICE; description = @"local host"; } -#endif else if (_type == GSPublicNotificationCenterType) { /* @@ -644,6 +639,10 @@ static NSDistributedNotificationCenter *netCenter = nil; { host = [h name]; } + if ([host isEqual: @""] == NO) + { + alternate = [service stringByAppendingFormat: @"-%@", host] ; + } } if ([host length] == 0 || [host isEqualToString: @"localhost"] == YES @@ -681,97 +680,88 @@ static NSDistributedNotificationCenter *netCenter = nil; _remote = [NSConnection rootProxyForConnectionWithRegisteredName: service host: host usingNameServer: ns]; - RETAIN(_remote); - - if (_type == GSPublicNotificationCenterType - && _remote == nil && [host isEqual: @""] == NO) + if (_remote == nil && alternate != nil) { _remote = [NSConnection rootProxyForConnectionWithRegisteredName: - [service stringByAppendingFormat: @"-%@", host] host: @"*" - usingNameServer: ns]; - RETAIN(_remote); + alternate host: @"*" usingNameServer: ns]; } - if (_remote != nil) + if (_remote == nil) { - NSConnection *c = [_remote connectionForProxy]; - Protocol *p = @protocol(GDNCProtocol); + NSString *cmd = nil; + NSArray *args = nil; + NSDate *limit; - [_remote setProtocolForProxy: p]; - - /* - * Ensure that this center can be used safely from different - * threads. - */ - [c enableMultipleThreads]; + cmd = [[NSSearchPathForDirectoriesInDomains( + GSToolsDirectory, NSSystemDomainMask, YES) objectAtIndex: 0] + stringByAppendingPathComponent: @"gdnc"]; - /* - * Ask to be told if the connection goes away. - */ - [[NSNotificationCenter defaultCenter] - addObserver: self - selector: @selector(_invalidated:) - name: NSConnectionDidDieNotification - object: c]; - [_remote registerClient: (id)self]; - } - else - { - static BOOL recursion = NO; - static NSString *cmd = nil; - static NSArray *args = nil; - - if (recursion == NO) - { - if (cmd == nil) - { - cmd = RETAIN([[NSSearchPathForDirectoriesInDomains( - GSToolsDirectory, NSSystemDomainMask, YES) objectAtIndex: 0] - stringByAppendingPathComponent: @"gdnc"]); - } - } - if (recursion == NO && cmd != nil) - { - NSLog(@"\nI couldn't contact the notification server for %@ -\n" + NSDebugMLLog(@"NSDistributedNotificationCenter", +@"\nI couldn't contact the notification server for %@ -\n" @"so I'm attempting to to start one - which will take a few seconds.\n" @"Trying to launch gdnc from %@ or a machine/operating-system subdirectory.\n" @"It is recommended that you start the notification server (gdnc) either at\n" @"login or (better) when your computer is started up.\n", description, [cmd stringByDeletingLastPathComponent]); - if (_type == GSNetworkNotificationCenterType) - { - args = [[NSArray alloc] initWithObjects: - @"-GSNetwork", @"YES", nil]; - } - else if (_type == GSPublicNotificationCenterType) - { - args = [[NSArray alloc] initWithObjects: - @"-GSPublic", @"YES", nil]; - } - else if ([host length] > 0) - { - args = [[NSArray alloc] initWithObjects: - @"-NSHost", host, nil]; - } - [NSTask launchedTaskWithLaunchPath: cmd arguments: args]; - [NSTimer scheduledTimerWithTimeInterval: 5.0 - invocation: nil - repeats: NO]; - [[NSRunLoop currentRunLoop] runUntilDate: - [NSDate dateWithTimeIntervalSinceNow: 5.0]]; - recursion = YES; - [self _connect]; - recursion = NO; - } - else + if (_type == GSNetworkNotificationCenterType) + { + args = [NSArray arrayWithObjects: + @"-GSNetwork", @"YES", nil]; + } + else if (_type == GSPublicNotificationCenterType) + { + args = [NSArray arrayWithObjects: + @"-GSPublic", @"YES", nil]; + } + else if ([host length] > 0) + { + args = [NSArray arrayWithObjects: + @"-NSHost", host, nil]; + } + [NSTask launchedTaskWithLaunchPath: cmd arguments: args]; + + limit = [NSDate dateWithTimeIntervalSinceNow: 5.0]; + while (_remote == nil && [limit timeIntervalSinceNow] > 0) + { + _remote = [NSConnection + rootProxyForConnectionWithRegisteredName: service + host: host usingNameServer: ns]; + if (_remote == nil && alternate != nil) + { + _remote = [NSConnection + rootProxyForConnectionWithRegisteredName: + alternate host: @"*" usingNameServer: ns]; + } + } + if (_remote == nil) { - recursion = NO; [NSException raise: NSInternalInconsistencyException format: @"unable to contact GDNC server -\n" - @"please check that the gdnc process is running."]; + @"please check that the gdnc process is running.\n" + @"I attempted to start it at '%@'\n", cmd]; } } + + RETAIN(_remote); + c = [_remote connectionForProxy]; + [_remote setProtocolForProxy: p]; + + /* + * Ensure that this center can be used safely from different + * threads. + */ + [c enableMultipleThreads]; + + /* + * Ask to be told if the connection goes away. + */ + [[NSNotificationCenter defaultCenter] + addObserver: self + selector: @selector(_invalidated:) + name: NSConnectionDidDieNotification + object: c]; + [_remote registerClient: (id)self]; } } diff --git a/Source/win32/NSMessagePortNameServerWin32.m b/Source/win32/NSMessagePortNameServerWin32.m index a7b899aca..b5b13b1c6 100644 --- a/Source/win32/NSMessagePortNameServerWin32.m +++ b/Source/win32/NSMessagePortNameServerWin32.m @@ -102,7 +102,7 @@ static void clean_up_names(void) UNISTR(registry), 0, L"", - REG_OPTION_NON_VOLATILE, + REG_OPTION_VOLATILE, STANDARD_RIGHTS_WRITE|STANDARD_RIGHTS_READ|KEY_SET_VALUE |KEY_QUERY_VALUE, NULL,