| // 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_ |