protobuf_grpc: use pthread

Fixes pagefaults.

This includes the changes provided by ssumpf in 6726aef.

Issue #190
This commit is contained in:
Sid Hussmann
2019-11-29 16:26:20 +01:00
committed by Christian Helmuth
parent c2d93a3fa9
commit 12d69338c5
9 changed files with 455 additions and 29 deletions

View File

@@ -0,0 +1,95 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <iostream>
#include <memory>
#include <string>
#include <grpcpp/grpcpp.h>
#ifdef BAZEL_BUILD
#include "examples/protos/helloworld.grpc.pb.h"
#else
#include "helloworld.grpc.pb.h"
#endif
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using helloworld::HelloRequest;
using helloworld::HelloReply;
using helloworld::Greeter;
class GreeterClient {
public:
GreeterClient(std::shared_ptr<Channel> channel)
: stub_(Greeter::NewStub(channel)) {}
// Assembles the client's payload, sends it and presents the response back
// from the server.
std::string SayHello(const std::string& user) {
// Data we are sending to the server.
HelloRequest request;
request.set_name(user);
// Container for the data we expect from the server.
HelloReply reply;
// Context for the client. It could be used to convey extra information to
// the server and/or tweak certain RPC behaviors.
ClientContext context;
// The actual RPC.
Status status = stub_->SayHello(&context, request, &reply);
// Act upon its status.
if (status.ok()) {
return reply.message();
} else {
std::cout << status.error_code() << ": " << status.error_message()
<< std::endl;
return "RPC failed";
}
}
private:
std::unique_ptr<Greeter::Stub> stub_;
};
int main(int argc, char** argv) {
// Instantiate the client. It requires a channel, out of which the actual RPCs
// are created. This channel models a connection to an endpoint (in this case,
// localhost at port 50051). We indicate that the channel isn't authenticated
// (use of InsecureChannelCredentials()).
std::cout << "GreeterClient started" << std::endl;
for (auto i = 0; i < 100; i++) {
std::shared_ptr<Channel> channel { grpc::CreateChannel(
"10.10.10.55:50051", grpc::InsecureChannelCredentials()) };
GreeterClient greeter(channel);
std::string user("world");
std::string reply = greeter.SayHello(user);
std::cout << "Greeter " << i << " received: " << reply << std::endl;
grpc::experimental::ChannelResetConnectionBackoff(channel.get());
}
std::cout << "GreeterClient stopped" << std::endl;
return 0;
}

View File

@@ -17,7 +17,6 @@ SRC_CC := greeter_client.cc
SRC_CC += helloworld.pb.cc
SRC_CC += helloworld.grpc.pb.cc
vpath greeter_client.cc $(GRPC_DIR)/examples/cpp/helloworld
vpath helloworld.proto $(PROTO_DIR)
$(SRC_CC): helloworld.grpc.pb.h

View File

@@ -49,8 +49,7 @@ class GreeterServiceImpl final : public Greeter::Service {
}
};
void RunServer() {
std::string server_address("10.10.10.55:50051");
void RunServer(const char* server_address) {
GreeterServiceImpl service;
ServerBuilder builder;

View File

@@ -1,4 +1,4 @@
#pragma once
void RunServer();
void RunServer(const char* server_address);

View File

@@ -3,6 +3,7 @@
#include <base/heap.h>
#include <base/log.h>
#include <base/thread.h>
#include <pthread.h>
#include "greeter_server.h"
enum { STACK_SIZE = 0xF000 };
@@ -10,37 +11,32 @@ enum { STACK_SIZE = 0xF000 };
namespace Grpc_server {
using namespace Genode;
class Runner;
class Server_main;
}
class Grpc_server::Runner : public Thread
static void *start_func(void* envp)
{
public:
Runner(Env& env)
: Thread(env, "runner", STACK_SIZE)
{
}
Genode::Env& env = *(reinterpret_cast<Genode::Env*>(envp));
Genode::Attached_rom_dataspace config { env, "config" };
Genode::String<256> server_address = config.xml().attribute_value("server_address", Genode::String<256>("0.0.0.0:8899"));
Libc::with_libc([&] () {
RunServer(server_address.string());
});
void entry() override
{
Libc::with_libc([] () {
RunServer();
});
}
};
return nullptr;
}
class Grpc_server::Server_main
{
private:
Env& _env;
Runner _runner { _env };
pthread_t _t;
public:
Server_main(Env& env)
: _env(env)
{
_runner.start();
pthread_create(&_t, 0, start_func, &env);
}
};