Je suis confronté à un problème de délai bizarre concernant l'envoi/réception de messages via les ports mach. Le concept de base de ma mise en œuvre est la suivante:Bizarre CFMessagePort
Plugin crée le port local → lance processus à distance qui envoie un message au dit port → renvoie les données reçues.
Voici la partie plugin:
static NSArray *returned=nil;
static CFDataRef handle_port (
CFMessagePortRef local,
SInt32 msgid,
CFDataRef d,
void *info
) {
NSPropertyListFormat format;
NSDictionary* ret = [NSPropertyListSerialization propertyListWithData:(NSData*)d
options: NSPropertyListImmutable
format: &format
error: nil];
returned=[NSArray arrayWithArray:[ret objectForKey:@"aKey"]]; //this is what I want returned from the portRet()
NSLog(@"returned array %@",returned);
return NULL;
}
NSArray* portRet(){
CFMessagePortRef port = CFMessagePortCreateLocal(kCFAllocatorDefault, CFSTR("com.someport"), handle_port, NULL, NULL);
CFRunLoopSourceRef source = CFMessagePortCreateRunLoopSource(kCFAllocatorDefault, port, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopCommonModes);
CFRelease(source);
int r=system("/path/someExecutable");
if(r !=0) NSLog(@"Program error");
//CFMessagePortInvalidate(port);
//CFRelease(port);
return returned; // always returns nil
}
Et la partie importante du code de someExecutable est le suivant:
int main(){
...
CFMessagePortRef port = CFMessagePortCreateRemote(NULL, CFSTR("com.someport"));
if(port == NULL) exit(1);
CFDataRef d=CFPropertyListCreateData(kCFAllocatorDefault,[NSDictionary dictionaryWithObject:anArray forKey:@"aKey"], kCFPropertyListXMLFormat_v1_0, 0, NULL);
CFMessagePortSendRequest (port, 0, d, 0, 0, NULL, NULL);
NSLog(@"Program is about to exit");
CFRelease(d);
...
exit(0);
}
Le message du processus à distance est envoyé gracieusement, mais la le rappel est appelé après le processus est terminé et le portRet()
a renvoyé une valeur nulle. Si j'invalide le port dans la fonction portRet()
, le message n'est jamais reçu.
Je ne peux pas comprendre la raison pour laquelle ce retard se produit. Ce que je veux accomplir est d'obtenir le rappel de port appelé avant les retours portRet()
. J'ai aussi essayé d'utiliser la principale file d'attente d'envoi au lieu d'un CFRunLoopSource
pour la planification de rappel du port:
CFMessagePortSetDispatchQueue(port, dispatch_get_main_queue());
Mais le résultat est à peu près la même chose. Je ne suis pas sûr de ce que je fais mal. Votre aide est grandement appréciée.