int main()

in remote/main.cpp [116:264]


int main(int argc, char* argv[]) {
  const boost::posix_time::ptime t0 =  boost::posix_time::microsec_clock::local_time();
  Log::setThreadName("main");
#if defined(OS_LINUX)
  CefRefPtr<CefApp> cefApp = nullptr;
  CefRefPtr<CefCommandLine> command_line = CefCommandLine::CreateCommandLine();
  command_line->InitFromArgv(argc, argv);
  const std::string& process_type = command_line->GetSwitchValue("type");
  if (process_type == "renderer" || process_type == "zygote")
    cefApp = new HelperApp();
  // On Linux the zygote process is used to spawn other process types. Since
  // we don't know what type of process it will be give it the renderer
  // client.

  CefMainArgs main_args(argc, argv);
  int exit_code = CefExecuteProcess(main_args, cefApp, nullptr);
  if (exit_code >= 0) {
    return exit_code;
  }
#elif WIN32
  // Execute subprocess (if necessary)
  CefRefPtr<CefApp> cefApp = nullptr;
  CefRefPtr<CefCommandLine> command_line = CefCommandLine::CreateCommandLine();
  command_line->InitFromString(::GetCommandLineW());
  const std::string& process_type = command_line->GetSwitchValue("type");
  const bool isMainBrowserProcess = process_type.empty();
  if (!isMainBrowserProcess) {
    // Initialize watchdog thread.
    DWORD parentProcessPid = GetParentProcessPid();
    HANDLE hParentProcess = OpenProcess(SYNCHRONIZE, FALSE, parentProcessPid);

    std::thread([hParentProcess]() {
      WaitForSingleObject(hParentProcess, INFINITE);
      ExitProcess(0);
    }).detach();
  }

  if (process_type == "renderer")
    cefApp = new HelperApp();

  CefMainArgs main_args(GetModuleHandle(0));
  const int result = CefExecuteProcess(main_args, cefApp, nullptr);
  if (result >= 0) {
    // If CefExecuteProcess called for the browser process (identified by no "type" command-line value)
    // it will return immediately with a value of -1.
    return result;
  }
#elif OS_MAC
  initMacApplication();
#endif

  const boost::posix_time::ptime t1 =  boost::posix_time::microsec_clock::local_time();
  fprintf(stdout, "Starting cer server. Pre-initialize spent %d ms.\n", (int)(t1 - t0).total_milliseconds());
  ServerApplication& app = ServerApplication::instance();
  if (!app.init(argc, argv)) {
    // Can't load CEF framework library.
    return 100;
  }

  if (!getBoolEnv("CEF_SERVER_DONT_CATCH_SIGNALS")) {
    setupCrashHandler();
  }

  const CommandLineArgs& cmdArgs = app.getCmdArgs();

#ifndef NDEBUG
  if (cmdArgs.waitDebugger()) {
    waitForDebug();
  }
#endif

  boost::posix_time::ptime t2 = boost::posix_time::microsec_clock::local_time();
  Log::trace("Start CEF initialization. ServerApplication initialization spent %d ms.", (t2 - t1).total_milliseconds());
  const bool success = CefUtils::initializeCef();
  if (!success) {
    Log::error("Cef initialization failed");
    return 101;
  }

  if (!getBoolEnv("CEF_SERVER_DONT_CATCH_SIGNALS")) {
    setupCrashHandler();
  }

  const boost::posix_time::ptime t3 =  boost::posix_time::microsec_clock::local_time();
  Log::trace("Create server transport. CEF initialization spent %d ms.", (t3 - t2).total_milliseconds());
  std::shared_ptr<TServerTransport> serverTransport;
  if (cmdArgs.useTcp()) {
    serverTransport = std::make_shared<TServerSocket>("127.0.0.1", cmdArgs.getPort());
  } else {
    std::string pipePath = cmdArgs.getPipe();
    if (pipePath.empty()) {
      Log::error("Pipe path is empty, exit.");
      return 102;
    }
#ifdef WIN32
    if (pipePath.rfind("\\\\.\\pipe\\", 0) != 0)
      pipePath = "\\\\.\\pipe\\" + pipePath;
    Log::info("Windows-pipe transport will be used, path=%s", pipePath.c_str());
    serverTransport = std::make_shared<PipeTransportServer>(pipePath);
#else
    std::remove(pipePath.c_str());
    serverTransport = std::make_shared<TServerSocket>(pipePath.c_str());
#endif //WIN32
  }
  std::shared_ptr<apache::thrift::TProcessorFactory> processorFactory = app.getProcessorFactory();
  std::shared_ptr<TThreadedServer> server = std::make_shared<TThreadedServer>(
      processorFactory,
      serverTransport,
      std::make_shared<TBufferedTransportFactory>(),
      std::make_shared<TBinaryProtocolFactory>());

  const boost::posix_time::ptime t4 =  boost::posix_time::microsec_clock::local_time();
  Log::trace("Start listening thread. Transport initialization spent %d ms.", (t4 - t3).total_milliseconds());
  std::thread servThread([=]() {
    Log::setThreadName("ServerListener");
    try {
      server->serve();
    } catch (TException& e) {
      Log::error("Exception in listening thread");
      Log::error(e.what());
    } catch (...) {
      Log::error("Unknown exception in listening thread");
    }
    Log::debug("Done, server stopped.");
  });

  const boost::posix_time::ptime t6 =  boost::posix_time::microsec_clock::local_time();
  Log::trace("Run CEF loop. Total initialization time %d ms.", (t6 - t0).total_milliseconds());

  CefUtils::runCefLoop();
  Log::debug("Finished message loop.");
  server->stop();
  servThread.join();
  app.onBeforeExit();
#ifndef WIN32
  if (!cmdArgs.useTcp())
    std::remove(cmdArgs.getPipe().c_str());
#endif  // WIN32
  if (cmdArgs.deleteRootCacheDir() && !app.isDefaultRoot()) {
    Log::debug("Remove root cache dir '%s'", app.getRootPath().c_str());
    try {
      std::filesystem::remove_all(app.getRootPath());
    } catch (const std::filesystem::filesystem_error& ex) {
      Log::error("Failed to remove root cache dir '%s'. Error: %s. Error code: %s", app.getRootPath().c_str(), ex.what(), ex.code().message().c_str());
    }
  }
  Log::debug("Buy [%s]!", cmdArgs.getTransportDesc().c_str());
  return 0;
}