| // Copyright 2019 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef SRC_VIRTUALIZATION_LIB_GUEST_INTERACTION_SERVER_SERVER_IMPL_H_ |
| #define SRC_VIRTUALIZATION_LIB_GUEST_INTERACTION_SERVER_SERVER_IMPL_H_ |
| |
| #include <grpc/support/log.h> |
| |
| #include "src/virtualization/lib/guest_interaction/common.h" |
| #include "src/virtualization/lib/guest_interaction/proto/guest_interaction.grpc.pb.h" |
| #include "src/virtualization/lib/guest_interaction/server/server_operation_state.h" |
| |
| #include <grpc++/grpc++.h> |
| |
| template <class T> |
| class ServerImpl { |
| public: |
| ServerImpl(){}; |
| ~ServerImpl(); |
| void Run(); |
| |
| private: |
| int GetSocket(); |
| void AcceptClient(int sockfd); |
| void HandleGetRequest(); |
| |
| std::unique_ptr<grpc::ServerCompletionQueue> cq_; |
| GuestInteractionService::AsyncService service_; |
| std::unique_ptr<grpc::Server> server_; |
| T platform_interface_; |
| }; |
| |
| template <class T> |
| ServerImpl<T>::~ServerImpl() { |
| server_->Shutdown(); |
| cq_->Shutdown(); |
| } |
| |
| template <class T> |
| int ServerImpl<T>::GetSocket() { |
| return platform_interface_.GetServerFD(VMADDR_CID_ANY, GUEST_INTERACTION_PORT); |
| } |
| |
| template <class T> |
| void ServerImpl<T>::AcceptClient(int sockfd) { |
| return platform_interface_.AcceptClient(server_.get(), sockfd); |
| } |
| |
| template <class T> |
| void ServerImpl<T>::Run() { |
| grpc::ServerBuilder builder; |
| builder.RegisterService(&service_); |
| cq_ = builder.AddCompletionQueue(); |
| server_ = builder.BuildAndStart(); |
| |
| int sockfd = GetSocket(); |
| std::cout << "Listening" << std::endl; |
| |
| new ExecCallData<T>(&service_, cq_.get()); |
| new GetCallData<T>(&service_, cq_.get()); |
| new PutCallData<T>(&service_, cq_.get()); |
| |
| void* tag; |
| bool ok; |
| gpr_timespec wait_time = {}; |
| |
| while (true) { |
| AcceptClient(sockfd); |
| |
| grpc::CompletionQueue::NextStatus status = cq_->AsyncNext(&tag, &ok, wait_time); |
| GPR_ASSERT(status != grpc::CompletionQueue::SHUTDOWN); |
| if (status == grpc::CompletionQueue::GOT_EVENT) { |
| static_cast<CallData*>(tag)->Proceed(ok); |
| } |
| } |
| } |
| |
| #endif // SRC_VIRTUALIZATION_LIB_GUEST_INTERACTION_SERVER_SERVER_IMPL_H_ |