brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.6 KiB · 1f1bba8 Raw
102 lines · cpp
1//===-- FifoFiles.cpp -------------------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "FifoFiles.h"10#include "JSONUtils.h"11 12#if !defined(_WIN32)13#include <sys/stat.h>14#include <sys/types.h>15#include <unistd.h>16#endif17 18#include <chrono>19#include <fstream>20#include <future>21#include <optional>22 23using namespace llvm;24 25namespace lldb_dap {26 27FifoFile::FifoFile(StringRef path) : m_path(path) {}28 29FifoFile::~FifoFile() {30#if !defined(_WIN32)31  unlink(m_path.c_str());32#endif33}34 35Expected<std::shared_ptr<FifoFile>> CreateFifoFile(StringRef path) {36#if defined(_WIN32)37  return createStringError(inconvertibleErrorCode(), "Unimplemented");38#else39  if (int err = mkfifo(path.data(), 0600))40    return createStringError(std::error_code(err, std::generic_category()),41                             "Couldn't create fifo file: %s", path.data());42  return std::make_shared<FifoFile>(path);43#endif44}45 46FifoFileIO::FifoFileIO(StringRef fifo_file, StringRef other_endpoint_name)47    : m_fifo_file(fifo_file), m_other_endpoint_name(other_endpoint_name) {}48 49Expected<json::Value> FifoFileIO::ReadJSON(std::chrono::milliseconds timeout) {50  // We use a pointer for this future, because otherwise its normal destructor51  // would wait for the getline to end, rendering the timeout useless.52  std::optional<std::string> line;53  std::future<void> *future =54      new std::future<void>(std::async(std::launch::async, [&]() {55        std::ifstream reader(m_fifo_file, std::ifstream::in);56        std::string buffer;57        std::getline(reader, buffer);58        if (!buffer.empty())59          line = buffer;60      }));61  if (future->wait_for(timeout) == std::future_status::timeout || !line)62    // Indeed this is a leak, but it's intentional. "future" obj destructor63    //  will block on waiting for the worker thread to join. And the worker64    //  thread might be stuck in blocking I/O. Intentionally leaking the  obj65    //  as a hack to avoid blocking main thread, and adding annotation to66    //  supress static code inspection warnings67 68    // coverity[leaked_storage]69    return createStringError(inconvertibleErrorCode(),70                             "Timed out trying to get messages from the " +71                                 m_other_endpoint_name);72  delete future;73  return json::parse(*line);74}75 76Error FifoFileIO::SendJSON(const json::Value &json,77                           std::chrono::milliseconds timeout) {78  bool done = false;79  std::future<void> *future =80      new std::future<void>(std::async(std::launch::async, [&]() {81        std::ofstream writer(m_fifo_file, std::ofstream::out);82        writer << JSONToString(json) << std::endl;83        done = true;84      }));85  if (future->wait_for(timeout) == std::future_status::timeout || !done) {86    // Indeed this is a leak, but it's intentional. "future" obj destructor will87    // block on waiting for the worker thread to join. And the worker thread88    // might be stuck in blocking I/O. Intentionally leaking the  obj as a hack89    // to avoid blocking main thread, and adding annotation to supress static90    // code inspection warnings"91 92    // coverity[leaked_storage]93    return createStringError(inconvertibleErrorCode(),94                             "Timed out trying to send messages to the " +95                                 m_other_endpoint_name);96  }97  delete future;98  return Error::success();99}100 101} // namespace lldb_dap102