Skip to content
Snippets Groups Projects
Commit d2786790 authored by George Nachman's avatar George Nachman
Browse files

Add iTermCallWithTimeout since 10.13 has a lot of system calls that never...

Add iTermCallWithTimeout since 10.13 has a lot of system calls that never return. Prevent proc_pidinfo for hanging for more than half a second.
parent 2b4ccebf
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -1267,6 +1267,8 @@
A61D16FC1AAFD5530013FCCA /* iTermBackgroundColorRun.h in Headers */ = {isa = PBXBuildFile; fileRef = A61D16FA1AAFD5530013FCCA /* iTermBackgroundColorRun.h */; };
A61D16FD1AAFD5530013FCCA /* iTermBackgroundColorRun.h in Headers */ = {isa = PBXBuildFile; fileRef = A61D16FA1AAFD5530013FCCA /* iTermBackgroundColorRun.h */; };
A61F8E301E62591800D315D0 /* iTermFakeUserDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = A61F8E2F1E62591800D315D0 /* iTermFakeUserDefaults.m */; };
A623D9471F8972750011F8C3 /* iTermCallWithTimeout.h in Headers */ = {isa = PBXBuildFile; fileRef = A623D9451F8972750011F8C3 /* iTermCallWithTimeout.h */; };
A623D9481F8972750011F8C3 /* iTermCallWithTimeout.m in Sources */ = {isa = PBXBuildFile; fileRef = A623D9461F8972750011F8C3 /* iTermCallWithTimeout.m */; };
A624231019CF6B0C00182C08 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A624230F19CF6B0C00182C08 /* Sparkle.framework */; };
A624231119CF6B0C00182C08 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A624230F19CF6B0C00182C08 /* Sparkle.framework */; };
A624231219CF6B0C00182C08 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A624230F19CF6B0C00182C08 /* Sparkle.framework */; };
Loading
Loading
@@ -3243,6 +3245,8 @@
A61D16FB1AAFD5530013FCCA /* iTermBackgroundColorRun.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = iTermBackgroundColorRun.m; sourceTree = "<group>"; };
A61F8E2E1E62591800D315D0 /* iTermFakeUserDefaults.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iTermFakeUserDefaults.h; sourceTree = "<group>"; };
A61F8E2F1E62591800D315D0 /* iTermFakeUserDefaults.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = iTermFakeUserDefaults.m; sourceTree = "<group>"; };
A623D9451F8972750011F8C3 /* iTermCallWithTimeout.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = iTermCallWithTimeout.h; sourceTree = "<group>"; };
A623D9461F8972750011F8C3 /* iTermCallWithTimeout.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = iTermCallWithTimeout.m; sourceTree = "<group>"; };
A624230F19CF6B0C00182C08 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = ThirdParty/Sparkle.framework; sourceTree = "<group>"; };
A624231319CF6B1600182C08 /* Growl.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Growl.framework; path = ThirdParty/Growl.framework; sourceTree = "<group>"; };
A624231819CF6DE000182C08 /* NMSSH.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NMSSH.framework; path = ThirdParty/NMSSH.framework; sourceTree = "<group>"; };
Loading
Loading
@@ -5724,6 +5728,8 @@
A65EC02E1F31800300AC0A6B /* iTermUpdateCadenceController.m */,
A65EC0311F3181E700AC0A6B /* NSTimer+iTerm.h */,
A65EC0321F3181E700AC0A6B /* NSTimer+iTerm.m */,
A623D9451F8972750011F8C3 /* iTermCallWithTimeout.h */,
A623D9461F8972750011F8C3 /* iTermCallWithTimeout.m */,
);
name = Helpers;
sourceTree = "<group>";
Loading
Loading
@@ -6869,6 +6875,7 @@
A667193D1DCE36C3000CE608 /* iTermHotkeyPreferencesModel.h in Headers */,
A667193E1DCE36C3000CE608 /* NSLocale+iTerm.h in Headers */,
A667193F1DCE36C3000CE608 /* iTermDirectoryTree.h in Headers */,
A623D9471F8972750011F8C3 /* iTermCallWithTimeout.h in Headers */,
A66719401DCE36C3000CE608 /* iTermOpenQuicklyCommands.h in Headers */,
A62A1F761E711BC000363EE9 /* iTermHelpMessageViewController.h in Headers */,
A66719411DCE36C3000CE608 /* iTermSystemVersion.h in Headers */,
Loading
Loading
@@ -8404,6 +8411,7 @@
A65EC0301F31800300AC0A6B /* iTermUpdateCadenceController.m in Sources */,
A66719661DCE3772000CE608 /* iTermWebSocketFrame.m in Sources */,
A65EC0341F3181E700AC0A6B /* NSTimer+iTerm.m in Sources */,
A623D9481F8972750011F8C3 /* iTermCallWithTimeout.m in Sources */,
A66EF82D1EF59CFC0005891A /* iTermRateLimitedUpdate.m in Sources */,
A66719601DCE3772000CE608 /* iTermAPIServer.m in Sources */,
A60BB38F1EB6A08A00D76C09 /* iTermProcessCollection.m in Sources */,
Loading
Loading
@@ -25,6 +25,7 @@
#import "NSFileManager+iTerm.h"
 
#import "iTermAdvancedSettingsModel.h"
#import "iTermCallWithTimeout.h"
#import "DebugLogging.h"
#import "iTermAdvancedSettingsModel.h"
#import "iTermAutoMasterParser.h"
Loading
Loading
@@ -232,35 +233,22 @@ NSString * const DirectoryLocationDomain = @"DirectoryLocationDomain";
if ([self fileHasForbiddenPrefix:filename additionalNetworkPaths:additionalNetworkPaths]) {
return NO;
}
static dispatch_queue_t statfsQueue;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
statfsQueue = dispatch_queue_create("com.iterm2.statfs", NULL);
});
 
// Do statfs in a background thread because it can hang when you're using certain network file systems.
__block BOOL ok = NO;
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
[filename retain];
dispatch_async(statfsQueue, ^{
struct statfs buf;
int rc = statfs([filename UTF8String], &buf);
if (rc != 0 || (buf.f_flags & MNT_LOCAL)) {
ok = [self fileExistsAtPath:filename];
} else {
ok = NO;
}
[filename release];
dispatch_group_leave(group);
});
// Wait up to half a second for the statfs to finish.
long timedOut = dispatch_group_wait(group,
dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)));
dispatch_release(group);
BOOL timedOut =
[[iTermCallWithTimeout instanceForIdentifier:@"statfs"] executeWithTimeout:0.5 block:^{
struct statfs buf;
int rc = statfs([filename UTF8String], &buf);
if (rc != 0 || (buf.f_flags & MNT_LOCAL)) {
ok = [self fileExistsAtPath:filename];
} else {
ok = NO;
}
[filename release];
}];
if (timedOutPtr) {
*timedOutPtr = !!timedOut;
*timedOutPtr = timedOut;
}
if (timedOut) {
DLog(@"Timed out doing statfs on %@", filename);
Loading
Loading
//
// iTermCallWithTimeout.h
// iTerm2SharedARC
//
// Created by George Nachman on 10/7/17.
//
#import <Foundation/Foundation.h>
@interface iTermCallWithTimeout : NSObject
+ (instancetype)instanceForIdentifier:(NSString *)identifier;
- (BOOL)executeWithTimeout:(NSTimeInterval)timeout
block:(void (^)(void))block;
@end
//
// iTermCallWithTimeout.m
// iTerm2SharedARC
//
// Created by George Nachman on 10/7/17.
//
#import "iTermCallWithTimeout.h"
@implementation iTermCallWithTimeout {
dispatch_queue_t _queue;
}
+ (instancetype)instanceForIdentifier:(NSString *)identifier {
static NSMutableDictionary *objects;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
objects = [NSMutableDictionary dictionary];
});
iTermCallWithTimeout *object = objects[identifier];
if (object == nil) {
object = [[self alloc] initWithIdentifier:identifier];
objects[identifier] = object;
}
return object;
}
- (instancetype)initWithIdentifier:(NSString *)identifier {
self = [super init];
if (self) {
_queue = dispatch_queue_create([[NSString stringWithFormat:@"com.iterm2.timeoutcall.%@", identifier] UTF8String],
NULL);
}
return self;
}
- (BOOL)executeWithTimeout:(NSTimeInterval)timeout block:(void (^)(void))block {
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
dispatch_async(_queue, ^{
block();
dispatch_group_leave(group);
});
// Wait up to half a second for the statfs to finish.
long timedOut = dispatch_group_wait(group,
dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeout * NSEC_PER_SEC)));
return !!timedOut;
}
@end
Loading
Loading
@@ -8,6 +8,7 @@
 
#import "iTermLSOF.h"
 
#import "iTermCallWithTimeout.h"
#import "iTermSocketAddress.h"
#import "ProcessCache.h"
#include <arpa/inet.h>
Loading
Loading
@@ -18,9 +19,11 @@
#include <sys/sysctl.h>
 
int iTermProcPidInfoWrapper(int pid, int flavor, uint64_t arg, void *buffer, int buffersize) {
@synchronized([iTermLSOF class]) {
return proc_pidinfo(pid, flavor, arg, buffer, buffersize);
}
__block int result;
BOOL timeout = [[iTermCallWithTimeout instanceForIdentifier:@"pidinfo"] executeWithTimeout:0.5 block:^{
result = proc_pidinfo(pid, flavor, arg, buffer, buffersize);
}];
return timeout ? -1 : result;
}
 
@implementation iTermLSOF {
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment