//===- subzero/src/IceBrowserCompileServer.h - Browser server ---*- C++ -*-===// // // The Subzero Code Generator // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// /// /// \file /// \brief Declares the browser-based compile server. /// //===----------------------------------------------------------------------===// #ifndef SUBZERO_SRC_ICEBROWSERCOMPILESERVER_H #define SUBZERO_SRC_ICEBROWSERCOMPILESERVER_H #include "IceClFlags.h" #include "IceCompileServer.h" #include "IceDefs.h" #include "IceELFStreamer.h" #include <atomic> #include <thread> namespace llvm { class QueueStreamer; class raw_fd_ostream; } // end of namespace llvm namespace Ice { /// The browser variant of the compile server. Compared to the commandline /// version, this version gets compile requests over IPC. Each compile request /// will have a slimmed down version of argc, argv while other flags are set to /// defaults that make sense in the browser case. The output file is specified /// via a posix FD, and input bytes are pushed to the server. class BrowserCompileServer : public CompileServer { BrowserCompileServer(const BrowserCompileServer &) = delete; BrowserCompileServer &operator=(const BrowserCompileServer &) = delete; class StringStream; public: BrowserCompileServer() : HadError(false) {} ~BrowserCompileServer() final; void run() final; ErrorCode &getErrorCode() final; /// Parse and set up the flags for compile jobs. void getParsedFlags(bool UseNumThreadsFromBrowser, uint32_t NumThreads, int argc, const char *const *argv); /// Creates the streams + context and starts the compile thread, handing off /// the streams + context. void startCompileThread(int OutFD); /// Call to push more bytes to the current input stream. Returns false on /// success and true on error. bool pushInputBytes(const void *Data, size_t NumBytes); /// Notify the input stream of EOF. void endInputStream(); /// Wait for the compile thread to complete then reset the state. void waitForCompileThread() { CompileThread.join(); if (Ctx->getErrorStatus()->value()) LastError.assign(Ctx->getErrorStatus()->value()); // Reset some state. The InputStream is deleted by the compiler so only // reset this to nullptr. Free and flush the rest of the streams. InputStream = nullptr; EmitStream.reset(nullptr); ELFStream.reset(nullptr); } StringStream &getErrorStream() { return *ErrorStream; } void setFatalError(const std::string &Reason); private: class StringStream { public: StringStream() : StrBuf(Buffer) {} const std::string &getContents() { return StrBuf.str(); } Ostream &getStream() { return StrBuf; } private: std::string Buffer; llvm::raw_string_ostream StrBuf; }; /// This currently only handles a single compile request, hence one copy of /// the state. std::unique_ptr<GlobalContext> Ctx; /// A borrowed reference to the current InputStream. The compiler owns the /// actual reference so the server must be careful not to access after the /// compiler is done. llvm::QueueStreamer *InputStream = nullptr; std::unique_ptr<Ostream> LogStream; std::unique_ptr<llvm::raw_fd_ostream> EmitStream; std::unique_ptr<StringStream> ErrorStream; std::unique_ptr<ELFStreamer> ELFStream; std::thread CompileThread; std::atomic<bool> HadError; }; } // end of namespace Ice #endif // SUBZERO_SRC_ICEBROWSERCOMPILESERVER_H