void PcapWriter::threadMain() { try { file_.writeGlobalHeader(); writeLoop(); file_.close(); } catch (const std::exception& ex) { LOG(ERROR) << "error writing to pcap file: " << folly::exceptionStr(ex); ex_ = std::current_exception(); } }
void Recorder::configure(const po::variables_map &vm) { // Check for config file and entry correctness auto config_table = oat::config::getConfigTable(vm); oat::config::checkKeys(config_keys_, config_table); // Sources if (vm.count("frame-sources")) { auto addrs = vm["frame-sources"].as< std::vector<std::string> >(); oat::config::checkForDuplicateSources(addrs); for (auto &a : addrs) writers_.emplace_back(oat::make_unique<FrameWriter>(a)); } if (vm.count("position-sources")) { auto addrs = vm["position-sources"].as< std::vector<std::string> >(); oat::config::checkForDuplicateSources(addrs); for (auto &a : addrs) writers_.emplace_back(oat::make_unique<PositionWriter>(a)); } if (writers_.size() == 0) throw std::runtime_error("At least one SOURCE must be provided."); else if (writers_.size() > 1) name_ = "recorder[" + writers_[0]->addr() + "..]"; else name_ = "recorder[" + writers_[0]->addr() + "]"; // Base file name oat::config::getValue(vm, config_table, "filename", file_name_); // Save folder oat::config::getValue(vm, config_table, "folder", save_path_); // Date oat::config::getValue(vm, config_table, "date", prepend_timestamp_); // Interactive control bool is_interactive = false; if (oat::config::getValue(vm, config_table, "interactive", is_interactive)) control_mode = LOCAL; // RPC control if (oat::config::getValue(vm, config_table, "rpc-endpoint", rpc_endpoint_)) control_mode = RPC; if (is_interactive && !rpc_endpoint_.empty()) { throw std::runtime_error("Recorder cannot be interactive and remote " "controlled at the same time. Choose either " "interactive or rpc-endpoint."); } // Writer specific options for (auto &w : writers_) w->configure(config_table, vm); // Start the recording tread writer_thread_ = std::thread( [this] { writeLoop(); } ); }