when I use NSTask to execute cmd in a loop, sometime the NSTask will hang, code is like this
- (BOOL)waitUntilExitWithTimeout:(CFTimeInterval)TO sendTerm:(BOOL)SENDTERM sendKill:(BOOL)SENDKILL
{
CFAbsoluteTime started;
CFAbsoluteTime passed;
BOOL exited = NO;
if (![self isRunning])
return YES;
int pro_pid = [self processIdentifier];
started = CFAbsoluteTimeGetCurrent();
for (
CFAbsoluteTime now = started;
!exited && ((passed = now - started) < TO);
now = CFAbsoluteTimeGetCurrent()
)
{
if (![self isRunning])
{
exited = YES;
} else {
CFAbsoluteTime sleepTime = 0.1;
useconds_t sleepUsec = round(sleepTime * 1000000.0);
if (sleepUsec == 0) sleepUsec = 1;
usleep(sleepUsec); // sleep for 0.1 sec
}
}
if (!exited)
{
//NSLog(@"%@ didn't exit after timeout of %0.2f sec", self, TO);
if (SENDTERM)
{
TO = 2; // 2 second timeout, waiting for SIGTERM to kill process
//NSLog(@"%@ sending SIGTERM", self);
//[self terminate];
// UNIX way
pid_t pid = [self processIdentifier];
kill(pid, SIGTERM);
started = CFAbsoluteTimeGetCurrent();
for (
CFAbsoluteTime now = started;
!exited && ((passed = now - started) < TO);
now = CFAbsoluteTimeGetCurrent()
)
{
if (![self isRunning])
{
exited = YES;
} else {
usleep(100000);
}
}
}
if (!exited && SENDKILL)
{
TO = 2; // 2 second timeout, waiting for SIGKILL to kill process
//NSLog(@"%@ sending SIGKILL", self);
pid_t pid = [self processIdentifier];
kill(pid, SIGKILL);
started = CFAbsoluteTimeGetCurrent();
for (
CFAbsoluteTime now = started;
!exited && ((passed = now - started) < TO);
now = CFAbsoluteTimeGetCurrent()
)
{
if (![self isRunning])
{
exited = YES;
} else {
usleep(100000); // sleep for 0.1 sec
}
}
}
}
return exited;
}
- (void) Exec(const char * cmdWithArgs)
{
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:@"/bin/sh"];
NSArray *arguments = [NSArray arrayWithObjects:
@"-c" ,
[NSString stringWithFormat:@"%s", cmdWithArgs],
nil];
[task setArguments: arguments];
NSPipe *pipe = [NSPipe pipe];
[task setStandardOutput: pipe];
[task launch];
NSFileHandle *file = [pipe fileHandleForReading];
NSData *data = [file readDataToEndOfFile];
[task waitUntilExitWithTimeout:30.0f sendTerm:YES sendKill:YES];
//sometime waitUntilExit will hang, sohttps://stackoverflow.com/questions/33423993/hanging-nstask-using-waituntilexit
//[task waitUntilExit];
[file closeFile];
}
std::string cmd = R"(netstat -rn | awk '/default/ {if ( index($6, "en0") > 0 ){print $2} }')";
while(1){
Exec(cmd.c_str());
}
when the test is hang, use lldb attached process, a deadlock occur. it seems caused by the lock in NSConcreteTask
anybody can help me ?
Post
Replies
Boosts
Views
Activity
I have an app, which need to get the authorization of bluetooth.
on macOS 12.0.1 (21A559), it seems something wrong.
[CBCentralManager authorization]
if the authorization is CBManagerAuthorizationDenied when the app is launch, even though I give the authorization in System Preferences。 [CBCentralManager authorization] also return CBManagerAuthorizationDenied.
Anybody can tell me what happen?
I developed a screen watermarking program that worked fine before macOS 12.4.
After upgrading to 12.4, "System Extension Blocked" pop-up cann't be click, but the other window is ok.
Any body can tell me the macOS 12.4 has do what to "System Extension Blocked" pop-up !!! my sample code like this
code-block
NSScreen *screen = [NSScreen screens][0];
CGFloat windowWidth = screen.frame.size.width;
CGFloat windowHeight = screen.frame.size.height;
CGFloat x = screen.frame.origin.x;
CGFloat y = screen.frame.origin.y;
MyView* view = [[MyView alloc]initWithFrame:NSMakeRect(0, 0, windowWidth, windowHeight)];
NSWindow* window = [[NSPanel alloc] initWithContentRect:NSMakeRect(0, 0, windowWidth, windowHeight)
styleMask: NSWindowStyleMaskBorderless | NSWindowStyleMaskNonactivatingPanel
backing:NSBackingStoreBuffered
defer:NO];
[window setOpaque:NO];
[window setBackgroundColor:[NSColor clearColor]];
[window setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces | NSWindowCollectionBehaviorFullScreenAuxiliary];
[window setIgnoresMouseEvents:YES];
[window setHasShadow:NO];
[window setLevel:NSScreenSaverWindowLevel];
[window setContentView:views];
[window makeKeyAndOrderFront:nil];
and draw in MyView
code-block
- (void)drawRect:(NSRect)dirtyRect
{
NSRect screen = [self bounds];
int SW = screen.size.width;
int SH = screen.size.height;
[[NSColor clearColor] set];
NSRectFill(screen);
NSString * strH= @"watermark test.";
NSMutableDictionary *md = [NSMutableDictionary dictionary];
[md setObject:[NSFont fontWithName:@"Times" size:80] forKey:NSFontAttributeName];
[strH drawAtPoint:NSMakePoint(SH*0.5, SH*0.5) withAttributes:md];
[self setNeedsDisplay:YES];
}