in idb_companion/Server/FBIDBServiceHandler.mm [1451:1517]
Status FBIDBServiceHandler::instruments_run(grpc::ServerContext *context, grpc::ServerReaderWriter<idb::InstrumentsRunResponse, idb::InstrumentsRunRequest> *stream)
{@autoreleasepool{
__block idb::InstrumentsRunRequest startRunRequest;
__block pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL);
__block bool finished_writing = NO;
dispatch_queue_t queue = dispatch_queue_create("com.facebook.idb.instruments.server", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
idb::InstrumentsRunRequest request;
stream->Read(&request);
startRunRequest = request;
});
FBInstrumentsConfiguration *configuration = translate_instruments_configuration(startRunRequest.start(), _commandExecutor.storageManager);
NSError *error = nil;
id<FBDataConsumer> consumer = [FBBlockDataConsumer asynchronousDataConsumerOnQueue:queue consumer:^(NSData *data) {
idb::InstrumentsRunResponse response;
response.set_log_output(data.bytes, data.length);
pthread_mutex_lock(&mutex);
if (!finished_writing) {
stream->Write(response);
}
pthread_mutex_unlock(&mutex);
}];
id<FBControlCoreLogger> logger = [FBControlCoreLoggerFactory compositeLoggerWithLoggers:@[
[FBControlCoreLoggerFactory loggerToConsumer:consumer],
_target.logger,
]];
FBInstrumentsOperation *operation = [[_target startInstruments:configuration logger:logger] block:&error];
if (!operation) {
pthread_mutex_lock(&mutex);
finished_writing = YES;
pthread_mutex_unlock(&mutex);
return Status(grpc::StatusCode::INTERNAL, error.localizedDescription.UTF8String);
}
__block idb::InstrumentsRunRequest stopRunRequest;
dispatch_sync(queue, ^{
idb::InstrumentsRunResponse response;
response.set_state(idb::InstrumentsRunResponse::State::InstrumentsRunResponse_State_RUNNING_INSTRUMENTS);
stream->Write(response);
idb::InstrumentsRunRequest request;
stream->Read(&request);
stopRunRequest = request;
});
if (![operation.stop succeeds:&error]) {
pthread_mutex_lock(&mutex);
finished_writing = YES;
pthread_mutex_unlock(&mutex);
return Status(grpc::StatusCode::INTERNAL, error.localizedDescription.UTF8String);
}
NSArray<NSString *> *postProcessArguments = [_commandExecutor.storageManager interpolateArgumentReplacements:extract_string_array(stopRunRequest.stop().post_process_arguments())];
dispatch_sync(queue, ^{
idb::InstrumentsRunResponse response;
response.set_state(idb::InstrumentsRunResponse::State::InstrumentsRunResponse_State_POST_PROCESSING);
stream->Write(response);
});
NSURL *processed = [[FBInstrumentsOperation postProcess:postProcessArguments traceDir:operation.traceDir queue:queue logger:logger] block:&error];
pthread_mutex_lock(&mutex);
finished_writing = YES;
pthread_mutex_unlock(&mutex);
if (!processed) {
return Status(grpc::StatusCode::INTERNAL, error.localizedDescription.UTF8String);
}
return drain_writer([FBArchiveOperations createGzippedTarForPath:processed.path queue:queue logger:_target.logger], stream);
}}