| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
- #pragma once
- #include "cmConfigure.h" // IWYU pragma: keep
- #include <condition_variable>
- #include <cstddef>
- #include <future>
- #include <memory>
- #include <mutex>
- #include <string>
- #include <thread>
- #include <cm3p/cppdap/io.h>
- #include <cm3p/uv.h>
- #include "cmDebuggerAdapter.h"
- #include "cmUVHandlePtr.h"
- namespace cmDebugger {
- class cmDebuggerPipeBase : public dap::ReaderWriter
- {
- public:
- cmDebuggerPipeBase(std::string name);
- void WaitForConnection();
- // dap::ReaderWriter implementation
- void close() final;
- size_t read(void* buffer, size_t n) final;
- bool write(const void* buffer, size_t n) final;
- protected:
- virtual void CloseConnection(){};
- template <typename T>
- void StartReading(uv_stream_t* stream)
- {
- uv_read_start(
- stream,
- // alloc_cb
- [](uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
- (void)handle;
- char* rawBuffer = new char[suggested_size];
- *buf =
- uv_buf_init(rawBuffer, static_cast<unsigned int>(suggested_size));
- },
- // read_cb
- [](uv_stream_t* readStream, ssize_t nread, const uv_buf_t* buf) {
- auto conn = static_cast<T*>(readStream->data);
- if (conn) {
- if (nread >= 0) {
- conn->BufferData(std::string(buf->base, buf->base + nread));
- } else {
- conn->close();
- }
- }
- delete[] (buf->base);
- });
- }
- void StopLoop();
- const std::string PipeName;
- std::thread LoopThread;
- cm::uv_loop_ptr Loop;
- cm::uv_pipe_ptr Pipe;
- std::mutex Mutex;
- std::condition_variable Connected;
- bool FailedToOpen = false;
- private:
- void BufferData(const std::string& data);
- void WriteInternal();
- cm::uv_async_ptr LoopExit;
- cm::uv_async_ptr WriteEvent;
- cm::uv_async_ptr PipeClose;
- std::string WriteBuffer;
- std::string ReadBuffer;
- std::condition_variable ReadReady;
- std::condition_variable WriteComplete;
- };
- class cmDebuggerPipeConnection
- : public cmDebuggerPipeBase
- , public cmDebuggerConnection
- , public std::enable_shared_from_this<cmDebuggerPipeConnection>
- {
- public:
- cmDebuggerPipeConnection(std::string name);
- ~cmDebuggerPipeConnection() override;
- void WaitForConnection() override
- {
- cmDebuggerPipeBase::WaitForConnection();
- }
- bool StartListening(std::string& errorMessage) override;
- std::shared_ptr<dap::Reader> GetReader() override;
- std::shared_ptr<dap::Writer> GetWriter() override;
- // dap::ReaderWriter implementation
- bool isOpen() override;
- // Used for unit test synchronization
- std::promise<void> StartedListening;
- private:
- void CloseConnection() override;
- void Connect(uv_stream_t* server);
- cm::uv_pipe_ptr ServerPipe;
- cm::uv_async_ptr ServerPipeClose;
- };
- class cmDebuggerPipeClient : public cmDebuggerPipeBase
- {
- public:
- using cmDebuggerPipeBase::cmDebuggerPipeBase;
- ~cmDebuggerPipeClient() override;
- void Start();
- // dap::ReaderWriter implementation
- bool isOpen() override;
- private:
- void CloseConnection() override;
- void Connect();
- void FailConnection();
- bool IsConnected = false;
- };
- } // namespace cmDebugger
|