Split bind API

Bind API is split into connect and startProcessingMessages calls.
This enables users to directly call connect and manage processing
messages on user threads.
This commit is contained in:
Puneetha Ramachandra
2020-12-01 09:19:41 -08:00
committed by Ben Clayton
parent ea6098df7f
commit e53575d272
3 changed files with 75 additions and 31 deletions

View File

@@ -52,17 +52,7 @@ class Impl : public dap::Session {
handlers.put(typeinfo, handler);
}
void bindNoThread(const std::shared_ptr<dap::Reader>& r,
const std::shared_ptr<dap::Writer>& w) override {
if (isBound.exchange(true)) {
handlers.error("Session is already bound!");
return;
}
reader = dap::ContentReader(r);
writer = dap::ContentWriter(w);
}
std::function<void()> OnDataAvailable() override {
std::function<void()> getPayload() override {
auto request = reader.read();
if (request.size() > 0) {
if (auto payload = processMessage(request)) {
@@ -72,8 +62,8 @@ class Impl : public dap::Session {
return {};
}
void bind(const std::shared_ptr<dap::Reader>& r,
const std::shared_ptr<dap::Writer>& w) override {
void connect(const std::shared_ptr<dap::Reader>& r,
const std::shared_ptr<dap::Writer>& w) override {
if (isBound.exchange(true)) {
handlers.error("Session is already bound!");
return;
@@ -81,14 +71,13 @@ class Impl : public dap::Session {
reader = dap::ContentReader(r);
writer = dap::ContentWriter(w);
}
void startProcessingMessages() override {
recvThread = std::thread([this] {
while (reader.isOpen()) {
auto request = reader.read();
if (request.size() > 0) {
if (auto payload = processMessage(request)) {
inbox.put(std::move(payload));
}
if (auto payload = getPayload()) {
inbox.put(std::move(payload));
}
}
});

View File

@@ -370,6 +370,45 @@ TEST_F(SessionTest, SendEventNoBind) {
ASSERT_TRUE(errored);
}
TEST_F(SessionTest, SingleThread) {
server->registerHandler(
[&](const dap::TestRequest&) { return createResponse(); });
// Explicitly connect and process request on this test thread instead of
// calling bind() which inturn starts processing messages immediately on a new
// thread.
auto client2server = dap::pipe();
auto server2client = dap::pipe();
client->connect(server2client, client2server);
server->connect(client2server, server2client);
auto request = createRequest();
auto response = client->send(request);
// Process request and response on this thread
if (auto payload = server->getPayload()) {
payload();
}
if (auto payload = client->getPayload()) {
payload();
}
auto got = response.get();
// Check response was received correctly.
ASSERT_EQ(got.error, false);
ASSERT_EQ(got.response.b, dap::boolean(true));
ASSERT_EQ(got.response.i, dap::integer(99));
ASSERT_EQ(got.response.n, dap::number(123.456));
ASSERT_EQ(got.response.a, dap::array<dap::integer>({5, 4, 3, 2, 1}));
ASSERT_EQ(got.response.o.size(), 3U);
ASSERT_EQ(got.response.o["one"].get<dap::integer>(), dap::integer(1));
ASSERT_EQ(got.response.o["two"].get<dap::number>(), dap::number(2));
ASSERT_EQ(got.response.o["three"].get<dap::string>(), dap::string("3"));
ASSERT_EQ(got.response.s, "ROGER");
ASSERT_EQ(got.response.o1, dap::optional<dap::integer>(50));
ASSERT_FALSE(got.response.o2.has_value());
}
TEST_F(SessionTest, Concurrency) {
std::atomic<int> numEventsHandled = {0};
std::atomic<bool> done = {false};