Check process exists if possible.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@25373 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2007-08-02 10:32:08 +00:00
parent fe6d9402d0
commit a3ed143043
2 changed files with 71 additions and 29 deletions

View file

@ -2,6 +2,7 @@
* Source/NSWorkspace.m: ([-launchedApplications]) check that each app
is still responding if it's more than 30 seconds since the last check.
If possible, check that processes still exist.
2007-07-31 Fred Kiefer <FredKiefer@gmx.de>

View file

@ -56,6 +56,7 @@
#include <Foundation/NSDistributedNotificationCenter.h>
#include <Foundation/NSConnection.h>
#include <Foundation/NSDebug.h>
#include <Foundation/NSProcessInfo.h>
#include <Foundation/NSThread.h>
#include <Foundation/NSURL.h>
#include <Foundation/NSValue.h>
@ -69,6 +70,12 @@
#include "GNUstepGUI/GSServicesManager.h"
#include "GNUstepGUI/GSDisplayServer.h"
/* Private method to check that a process exists.
*/
@interface NSProcessInfo (Private)
+ (BOOL)_exists: (int)pid;
@end
#define PosixExecutePermission (0111)
static NSImage *folderImage = nil;
@ -1413,9 +1420,7 @@ inFileViewerRootedAtPath: (NSString*)rootFullpath
*/
- (NSArray*) launchedApplications
{
static NSDate *lastCheck = nil;
NSArray *apps = nil;
unsigned count;
NS_DURING
{
@ -1433,40 +1438,76 @@ inFileViewerRootedAtPath: (NSString*)rootFullpath
NS_ENDHANDLER
if (apps == nil)
{
static NSDate *lastCheck = nil;
unsigned count;
apps = GSLaunched(nil, NO);
}
/* If it's over 30 seconds since the last check ... try to contact
* all launched applications to ensure that none have crashed.
*/
if (lastCheck != nil && [lastCheck timeIntervalSinceNow] > -30.0)
{
return apps;
}
ASSIGN(lastCheck, [NSDate date]);
count = [apps count];
count = [apps count];
while (count-- > 0)
{
NSString *name;
name = [[apps objectAtIndex: count] objectForKey: @"NSApplicationName"];
if (name != nil)
if ([NSProcessInfo respondsToSelector: @selector(_exists:)] == YES)
{
CREATE_AUTORELEASE_POOL(arp);
BOOL found = NO;
if ([self _connectApplication: name alert: NO] != nil)
/* Check and remove apps whose pid no loinger exists
*/
while (count-- > 0)
{
found = YES;
int pid;
NSString *name;
name = [[apps objectAtIndex: count]
objectForKey: @"NSApplicationName"];
pid = [[[apps objectAtIndex: count]
objectForKey: @"NSApplicationProcessIdentifier"] intValue];
if (pid > 0 && [name length] > 0)
{
if ([NSProcessInfo _exists: pid] == NO)
{
NSMutableArray *m = [apps mutableCopy];
GSLaunched([NSNotification notificationWithName:
NSWorkspaceDidTerminateApplicationNotification
object: self
userInfo: [NSDictionary dictionaryWithObject: name
forKey: @"NSApplicationName"]], NO);
[m removeObjectAtIndex: count];
apps = AUTORELEASE(m);
}
}
}
RELEASE(arp);
if (found == NO)
{
NSMutableArray *m = [apps mutableCopy];
}
[m removeObjectAtIndex: count];
apps = AUTORELEASE(m);
/* If it's over 30 seconds since the last check ... try to contact
* all launched applications to ensure that none have crashed.
*/
if (lastCheck == nil || [lastCheck timeIntervalSinceNow] < -30.0)
{
ASSIGN(lastCheck, [NSDate date]);
while (count-- > 0)
{
NSString *name;
name = [[apps objectAtIndex: count]
objectForKey: @"NSApplicationName"];
if (name != nil)
{
CREATE_AUTORELEASE_POOL(arp);
BOOL found = NO;
if ([self _connectApplication: name alert: NO] != nil)
{
found = YES;
}
RELEASE(arp);
if (found == NO)
{
NSMutableArray *m = [apps mutableCopy];
[m removeObjectAtIndex: count];
apps = AUTORELEASE(m);
}
}
}
}
}