LCOV - code coverage report
Current view: top level - ipc/server/include - IIpcServer.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 4 4
Test Date: 2025-02-18 13:13:53 Functions: 100.0 % 4 4

            Line data    Source code
       1              : /*
       2              :  * If not stated otherwise in this file or this component's LICENSE file the
       3              :  * following copyright and licenses apply:
       4              :  *
       5              :  * Copyright 2022 Sky UK
       6              :  *
       7              :  * Licensed under the Apache License, Version 2.0 (the "License");
       8              :  * you may not use this file except in compliance with the License.
       9              :  * You may obtain a copy of the License at
      10              :  *
      11              :  * http://www.apache.org/licenses/LICENSE-2.0
      12              :  *
      13              :  * Unless required by applicable law or agreed to in writing, software
      14              :  * distributed under the License is distributed on an "AS IS" BASIS,
      15              :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      16              :  * See the License for the specific language governing permissions and
      17              :  * limitations under the License.
      18              :  */
      19              : 
      20              : #ifndef FIREBOLT_RIALTO_IPC_I_IPC_SERVER_H_
      21              : #define FIREBOLT_RIALTO_IPC_I_IPC_SERVER_H_
      22              : 
      23              : #include <google/protobuf/message.h>
      24              : #include <google/protobuf/service.h>
      25              : 
      26              : #include <functional>
      27              : #include <map>
      28              : #include <memory>
      29              : #include <string>
      30              : #include <utility>
      31              : 
      32              : namespace firebolt::rialto::ipc
      33              : {
      34              : /**
      35              :  * @brief Interface to object describing a client connected to the server.
      36              :  *
      37              :  *  An object of this interface is provided in the callbacks for when a client
      38              :  *  connects / disconnects.  The interface can be used to query details above
      39              :  *  the client and send it asynchronous events.
      40              :  */
      41              : class IClient
      42              : {
      43              : public:
      44          246 :     IClient() = default;
      45          246 :     virtual ~IClient() = default;
      46              : 
      47              :     IClient(const IClient &) = delete;
      48              :     IClient &operator=(const IClient &) = delete;
      49              :     IClient(IClient &&) = delete;
      50              :     IClient &operator=(IClient &&) = delete;
      51              : 
      52              : public:
      53              :     /**
      54              :      * @brief Gets the pid of the client that created the connection.
      55              :      *
      56              :      * \threadsafe
      57              :      *
      58              :      * @retval the pid.
      59              :      */
      60              :     virtual pid_t getClientPid() const = 0;
      61              : 
      62              :     /**
      63              :      * @brief Gets the userIdof the client that created the connection.
      64              :      *
      65              :      * \threadsafe
      66              :      *
      67              :      * @retval the userId.
      68              :      */
      69              :     virtual uid_t getClientUserId() const = 0;
      70              : 
      71              :     /**
      72              :      * @brief Gets the groupId of the client that created the connection.
      73              :      *
      74              :      * \threadsafe
      75              :      *
      76              :      * @retval the groupId.
      77              :      */
      78              :     virtual gid_t getClientGroupId() const = 0;
      79              : 
      80              :     /**
      81              :      * @brief Tells the server to disconnect the client.
      82              :      *
      83              :      * \threadsafe
      84              :      *
      85              :      * Typically you'd call this in the clientConnected method if you didn't want to accept the
      86              :      * client's connection.
      87              :      */
      88              :     virtual void disconnect() = 0;
      89              : 
      90              :     /**
      91              :      * @brief Adds a service implementation for the client.
      92              :      *
      93              :      * \threadsafe
      94              :      *
      95              :      * After this the client will be able to call methods on the service.
      96              :      *
      97              :      * @param[in] service  : service to export.
      98              :      */
      99              :     virtual void exportService(const std::shared_ptr<google::protobuf::Service> &service) = 0;
     100              : 
     101              :     /**
     102              :      * @brief Sends a message out to the client connection.
     103              :      *
     104              :      * \threadsafe
     105              :      *
     106              :      * This method is thread safe
     107              :      * and may be called from any context; internally it will queue the message
     108              :      * on the client's message queue and the server process will send it
     109              :      *
     110              :      * @param[in] message  : message to send.
     111              :      *
     112              :      * @retval true on success, false otherwise.
     113              :      */
     114              :     virtual bool sendEvent(const std::shared_ptr<google::protobuf::Message> &message) = 0;
     115              : 
     116              :     /**
     117              :      * @brief The server object.
     118              :      *
     119              :      * \threadsafe
     120              :      *
     121              :      * It is safe to hold a
     122              :      * shared_ptr to this object after the client has disconnected, but obviously
     123              :      * sendEvent will fail and data like pid and userId will be invalid.
     124              :      *
     125              :      * @retval true if the client is still conn
     126              :      */
     127              :     virtual bool isConnected() const = 0;
     128              : };
     129              : 
     130              : /**
     131              :  * @brief The server object.
     132              :  *
     133              :  *  You must run the server as part of an external event loop implementation, you
     134              :  *  can do that by setting up a loop that calls wait() and then process(). Or
     135              :  *  you can get the fd() and add it to an external poll loop, and when woken call
     136              :  *  process().
     137              :  */
     138              : class IServer
     139              : {
     140              : public:
     141          236 :     IServer() = default;
     142          236 :     virtual ~IServer() = default;
     143              : 
     144              :     IServer(const IServer &) = delete;
     145              :     IServer &operator=(const IServer &) = delete;
     146              :     IServer(IServer &&) = delete;
     147              :     IServer &operator=(IServer &&) = delete;
     148              : 
     149              :     /**
     150              :      * @brief Creates the listening socket to accept new connections.
     151              :      *
     152              :      * \threadsafe
     153              :      *
     154              :      * This does not blockwaiting for connections, it just creates the socket and adds to the poll loop.
     155              :      *
     156              :      * @retval true on success, false otherwise.
     157              :      */
     158              :     inline bool addSocket(const std::string &socketPath) { return addSocket(socketPath, nullptr, nullptr); }
     159              :     inline bool addSocket(const std::string &socketPath,
     160              :                           std::function<void(const std::shared_ptr<IClient> &)> clientConnectedCb)
     161              :     {
     162              :         return addSocket(socketPath, std::move(clientConnectedCb), nullptr);
     163              :     }
     164              :     virtual bool addSocket(const std::string &socketPath,
     165              :                            std::function<void(const std::shared_ptr<IClient> &)> clientConnectedCb,
     166              :                            std::function<void(const std::shared_ptr<IClient> &)> clientDisconnectedCb) = 0;
     167              : 
     168              :     /**
     169              :      * @brief Create a client.
     170              :      *
     171              :      * \threadsafe
     172              :      *
     173              :      * Given a file descriptor corresponding to one end of a socket, this function
     174              :      * will create a client (std::shared_ptr<Client>) and add the new client to
     175              :      * the internal clients list.  At that point, the client is initialized and
     176              :      * ready to run, as if the client had connected to the servers listening socket.
     177              :      *
     178              :      * The other end of the socket can be passed to firebolt::rialto::ipc::Channel::connect(int sockFd)
     179              :      * function to create a client side IPC channel.
     180              :      *
     181              :      * When the other end of the socket is closed the clientDisconnectedCb will
     182              :      * be called.
     183              :      *
     184              :      * The socketFd must be a unix domain socket of type SOCK_SEQPACKET, if a different
     185              :      * socket type then this will fail and return a null std::shared_ptr.
     186              :      *
     187              :      * The server will dup the socketFd on success, so the caller can (and should)
     188              :      * close the socketFd after this call completes if it no longer needs the socket.
     189              :      *
     190              :      * @param[in] socketFd              : The file descriptor for the socket.
     191              :      * @param[in] clientDisconnectedCb  : Callback to be called on the closing of the socket.
     192              :      *
     193              :      * @retval client on success, nullptr otherwise.
     194              :      */
     195              :     inline std::shared_ptr<IClient> addClient(int socketFd) { return addClient(socketFd, nullptr); }
     196              :     virtual std::shared_ptr<IClient>
     197              :     addClient(int socketFd, std::function<void(const std::shared_ptr<IClient> &)> clientDisconnectedCb) = 0;
     198              : 
     199              :     /**
     200              :      * @brief Returns an fd that can be added to an external event loop.  This is NOT the
     201              :      * server socket fd.
     202              :      *
     203              :      * @retval >= 0 on success, -1 otherwise.
     204              :      */
     205              :     virtual int fd() const = 0;
     206              : 
     207              :     /** Waits for any I/O to occur on the socket or timeout from a method call.
     208              :      * The call will block for a maximum of  timeoutMSecs, to make the call wait
     209              :      * indefinitely pass -1.
     210              :      *
     211              :      * @param[in] timeoutMSecs  : The time to wait for I/O.
     212              :      *
     213              :      * @retval false if there was an error , true otherwise
     214              :      */
     215              :     inline bool wait() { return this->wait(-1); }
     216              :     virtual bool wait(int timeoutMSecs) = 0;
     217              : 
     218              :     /**
     219              :      * @brief This is the heart of the server, it is where we wait for new incoming
     220              :      * connections or data from clients, and send data back to clients.
     221              :      *
     222              :      * @retval false if there was an error, true otherwise
     223              :      */
     224              :     virtual bool process() = 0;
     225              : };
     226              : 
     227              : } // namespace firebolt::rialto::ipc
     228              : 
     229              : #endif // FIREBOLT_RIALTO_IPC_I_IPC_SERVER_H_
        

Generated by: LCOV version 2.0-1