Ejemplo n.º 1
0
lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) {
  Communication *comm = (Communication *)p;

  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION));

  if (log)
    log->Printf("%p Communication::ReadThread () thread starting...", p);

  uint8_t buf[1024];

  Status error;
  ConnectionStatus status = eConnectionStatusSuccess;
  bool done = false;
  while (!done && comm->m_read_thread_enabled) {
    size_t bytes_read = comm->ReadFromConnection(
        buf, sizeof(buf), std::chrono::seconds(5), status, &error);
    if (bytes_read > 0)
      comm->AppendBytesToCache(buf, bytes_read, true, status);
    else if ((bytes_read == 0) && status == eConnectionStatusEndOfFile) {
      if (comm->GetCloseOnEOF())
        comm->Disconnect();
      comm->AppendBytesToCache(buf, bytes_read, true, status);
    }

    switch (status) {
    case eConnectionStatusSuccess:
      break;

    case eConnectionStatusEndOfFile:
      done = true;
      break;
    case eConnectionStatusError: // Check GetError() for details
      if (error.GetType() == eErrorTypePOSIX && error.GetError() == EIO) {
        // EIO on a pipe is usually caused by remote shutdown
        comm->Disconnect();
        done = true;
      }
      if (error.Fail())
        LLDB_LOG(log, "error: {0}, status = {1}", error,
                 Communication::ConnectionStatusAsCString(status));
      break;
    case eConnectionStatusInterrupted: // Synchronization signal from
                                       // SynchronizeWithReadThread()
      // The connection returns eConnectionStatusInterrupted only when there is
      // no input pending to be read, so we can signal that.
      comm->BroadcastEvent(eBroadcastBitNoMorePendingInput);
      break;
    case eConnectionStatusNoConnection:   // No connection
    case eConnectionStatusLostConnection: // Lost connection while connected to
                                          // a valid connection
      done = true;
      LLVM_FALLTHROUGH;
    case eConnectionStatusTimedOut: // Request timed out
      if (error.Fail())
        LLDB_LOG(log, "error: {0}, status = {1}", error,
                 Communication::ConnectionStatusAsCString(status));
      break;
    }
  }
  log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION);
  if (log)
    log->Printf("%p Communication::ReadThread () thread exiting...", p);

  comm->m_read_thread_did_exit = true;
  // Let clients know that this thread is exiting
  comm->BroadcastEvent(eBroadcastBitNoMorePendingInput);
  comm->BroadcastEvent(eBroadcastBitReadThreadDidExit);
  return NULL;
}