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:
committed by
Ben Clayton
parent
ea6098df7f
commit
e53575d272
@@ -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));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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};
|
||||
|
||||
Reference in New Issue
Block a user