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