/// /// Copyright 2015-2017 Oliver Giles /// /// This file is part of Laminar /// /// Laminar is free software: you can redistribute it and/or modify /// it under the terms of the GNU General Public License as published by /// the Free Software Foundation, either version 3 of the License, or /// (at your option) any later version. /// /// Laminar is distributed in the hope that it will be useful, /// but WITHOUT ANY WARRANTY; without even the implied warranty of /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /// GNU General Public License for more details. /// /// You should have received a copy of the GNU General Public License /// along with Laminar. If not, see /// #ifndef LAMINAR_SERVER_H_ #define LAMINAR_SERVER_H_ #include #include #include #include #include struct LaminarInterface; struct Http; struct Rpc; // This class abstracts the HTTP/Websockets and Cap'n Proto RPC interfaces // and manages the program's asynchronous event loop class Server final : public kj::TaskSet::ErrorHandler { public: // Initializes the server with a LaminarInterface to handle requests from // HTTP/Websocket or RPC clients and bind addresses for each of those // interfaces. See the documentation for kj::AsyncIoProvider::getNetwork // for a description of the address format Server(LaminarInterface& li, kj::StringPtr rpcBindAddress, kj::StringPtr httpBindAddress); ~Server(); void start(); void stop(); // add a file descriptor to be monitored for output. The callback will be // invoked with the read data kj::Promise readDescriptor(int fd, std::function cb); void addTask(kj::Promise &&task); // add a one-shot timer callback kj::Promise addTimeout(int seconds, std::function cb); // get a promise which resolves when a child process exits kj::Promise onChildExit(kj::Maybe& pid); // add a path to be watched for changes void addWatchPath(const char* dpath); private: kj::Promise acceptRpcClient(kj::Own&& listener); kj::Promise handleFdRead(kj::AsyncInputStream* stream, char* buffer, std::function cb); void taskFailed(kj::Exception&& exception) override; private: int efd_quit; LaminarInterface& laminarInterface; kj::AsyncIoContext ioContext; kj::Own listeners; kj::TaskSet childTasks; kj::Maybe> reapWatch; int inotify_fd; kj::Maybe> pathWatch; // TODO: restructure so this isn't necessary friend class ServerTest; kj::PromiseFulfillerPair httpReady; // TODO: WIP kj::Own http; kj::Own rpc; }; #endif // LAMINAR_SERVER_H_