Por que não posso usar estruturas de cacau em diferentes processos bifurcados?
Eu estava brincando com oNSSound
classe para reproduzir um som em um processo em segundo plano do meu próprio modo de não bloquear a entrada do usuário. Eu decidi ligarfork()
mas isso está me dando problemas. No exato momento em que o som é alocado, as falhas do processo bifurcadas. O engraçado é se eu construir um exemplo que só chamafork()
, então o processo filho pode chamarNSSound
sem problemas, as falhas só acontecem se eu tentar usar outras APIs de cacauantes afork()
ligar. Veja este exemplo com ocrashme?()
chamadas comentadas:
#import <AppKit/AppKit.h>
#import <math.h>
#define FILENAME \
"/System/Library/Components/CoreAudio.component/" \
"Contents/SharedSupport/SystemSounds/dock/drag to trash.aif"
void crashme1(void)
{
NSString *path = [[NSString alloc] initWithUTF8String:"false file"];
NSSound *sound = [[NSSound alloc]
initWithContentsOfFile:path byReference:YES];
}
void crashme2(void)
{
NSInteger tag = 0;
[[NSWorkspace sharedWorkspace]
performFileOperation:NSWorkspaceRecycleOperation
source:@"." destination:nil
files:[NSArray arrayWithObject:@"false file"] tag:&tag];
}
double playAif(void)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *path = [[NSString alloc] initWithUTF8String:FILENAME];
NSSound *sound = [[NSSound alloc]
initWithContentsOfFile:path byReference:YES];
[path release];
if (!sound) {
[pool release];
return -1;
}
const double ret = [sound duration];
[sound play];
[sound autorelease];
[pool release];
return ret;
}
int main(int argc, char *argv[])
{
//crashme1();
//crashme2();
int childpid = fork();
if (0 == childpid) {
printf("Starting playback\n");
double wait = playAif();
sleep(ceil(wait));
wait = playAif();
sleep(ceil(wait));
printf("Finished playback\n");
}
return 0;
}
Quando eu executo isso a partir da linha de comando, funciona, mas se eu descomentar uma das chamadas paracrashme?()
funções a reprodução no processo bifurcado nunca é iniciada. É porque qualquer uma das APIs do framework Cocoa não ésinal assíncrono seguro? Existe alguma maneira de tornar seguro o sinal assíncrono de chamadas, envolvendo-os de alguma forma?