Status FBIDBServiceHandler::instruments_run()

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);
}}