Perform port/name cleanup on startup.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@29095 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2009-12-03 09:07:10 +00:00
parent a961de6c5d
commit ae04fdffe6
3 changed files with 105 additions and 0 deletions

View file

@ -1,3 +1,12 @@
2009-12-02 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSMessagePortNameServer.m:
* Source/NSMessagePort.m:
On initialisation, remove any old ports/names for the current process
idntifier. Also remove ports/names for processes which don't exist.
Avoids any possibility of nameserver confusion between two processes
with the same ID.
2009-12-01 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSMessagePortNameServer.m: Tolerate '*' host name.

View file

@ -91,6 +91,10 @@
#include <sys/stropts.h>
#endif
@interface NSProcessInfo (private)
+ (BOOL) _exists: (int)pid;
@end
/*
* Largest chunk of data possible in DO
*/
@ -1120,12 +1124,56 @@ typedef struct {
{
if (self == [NSMessagePort class])
{
NSFileManager *mgr;
NSString *path;
NSString *pref;
NSString *file;
NSEnumerator *files;
messagePortClass = self;
messagePortMap = NSCreateMapTable(NSNonRetainedObjectMapKeyCallBacks,
NSNonOwnedPointerMapValueCallBacks, 0);
messagePortLock = [GSLazyRecursiveLock new];
atexit(clean_up_sockets);
/* It's possible that an old process, with the same process ID as
* this one, got forcibly killed or crashed so that clean_up_sockets
* was never called.
* To deal with that unlikely situation, we need to remove all such
* ports which have been left over.
*/
path = NSTemporaryDirectory();
path = [path stringByAppendingPathComponent: @"NSMessagePort"];
path = [path stringByAppendingPathComponent: @"ports"];
pref = [NSString stringWithFormat: @"%i.",
[[NSProcessInfo processInfo] processIdentifier]];
mgr = [NSFileManager defaultManager];
files = [[mgr directoryContentsAtPath: path] objectEnumerator];
while ((file = [files nextObject]) != nil)
{
NSString *old = [path stringByAppendingPathComponent: file];
if (YES == [file hasPrefix: pref])
{
NSDebugMLLog(@"NSMessagePort", @"Removing old port %@", old);
[mgr removeFileAtPath: old handler: nil];
}
else
{
int pid = [file intValue];
if (pid > 0)
{
if (NO == [NSProcessInfo _exists: pid])
{
NSDebugMLLog(@"NSMessagePort",
@"Removing old port %@ for process %d", old, pid);
[mgr removeFileAtPath: old handler: nil];
}
}
}
}
}
}

View file

@ -57,6 +57,9 @@
(sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
#endif
@interface NSProcessInfo (private)
+ (BOOL) _exists: (int)pid;
@end
static NSRecursiveLock *serverLock = nil;
static NSMessagePortNameServer *defaultServer = nil;
@ -116,10 +119,55 @@ static void clean_up_names(void)
{
if (self == [NSMessagePortNameServer class])
{
NSFileManager *mgr;
NSString *path;
NSString *pref;
NSString *file;
NSEnumerator *files;
serverLock = [NSRecursiveLock new];
portToNamesMap = NSCreateMapTable(NSNonRetainedObjectMapKeyCallBacks,
NSObjectMapValueCallBacks, 0);
atexit(clean_up_names);
/* It's possible that an old process, with the same process ID as
* this one, got forcibly killed or crashed so that clean_up_names
* was never called.
* To deal with that unlikely situation, we need to remove all such
* names which have been left over.
*/
path = NSTemporaryDirectory();
path = [path stringByAppendingPathComponent: @"NSMessagePort"];
path = [path stringByAppendingPathComponent: @"names"];
pref = [NSString stringWithFormat: @"%i.",
[[NSProcessInfo processInfo] processIdentifier]];
mgr = [NSFileManager defaultManager];
files = [[mgr directoryContentsAtPath: path] objectEnumerator];
while ((file = [files nextObject]) != nil)
{
NSString *old = [path stringByAppendingPathComponent: file];
NSString *port = [NSString stringWithContentsOfFile: old];
if (YES == [port hasPrefix: pref])
{
NSDebugMLLog(@"NSMessagePort", @"Removing old name %@", old);
[mgr removeFileAtPath: old handler: nil];
}
else
{
int pid = [port intValue];
if (pid > 0)
{
if (NO == [NSProcessInfo _exists: pid])
{
NSDebugMLLog(@"NSMessagePort",
@"Removing old name %@ for process %d", old, pid);
[mgr removeFileAtPath: old handler: nil];
}
}
}
}
}
}