[clang-tools-extra] r294747 - [clangd] Refactor stream output into a single thread-safe output object.
Benjamin Kramer via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 10 06:08:41 PST 2017
Author: d0k
Date: Fri Feb 10 08:08:40 2017
New Revision: 294747
URL: http://llvm.org/viewvc/llvm-project?rev=294747&view=rev
Log:
[clangd] Refactor stream output into a single thread-safe output object.
This abstracts away the passing of raw_ostreams everywhere, thread
safety will be used soon.
Modified:
clang-tools-extra/trunk/clangd/ClangDMain.cpp
clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp
clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h
clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp
clang-tools-extra/trunk/clangd/ProtocolHandlers.h
Modified: clang-tools-extra/trunk/clangd/ClangDMain.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ClangDMain.cpp?rev=294747&r1=294746&r2=294747&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ClangDMain.cpp (original)
+++ clang-tools-extra/trunk/clangd/ClangDMain.cpp Fri Feb 10 08:08:40 2017
@@ -19,6 +19,7 @@ using namespace clang::clangd;
int main(int argc, char *argv[]) {
llvm::raw_ostream &Outs = llvm::outs();
llvm::raw_ostream &Logs = llvm::errs();
+ JSONOutput Out(Outs, Logs);
// Change stdin to binary to not lose \r\n on windows.
llvm::sys::ChangeStdinToBinary();
@@ -26,24 +27,24 @@ int main(int argc, char *argv[]) {
// Set up a document store and intialize all the method handlers for JSONRPC
// dispatching.
DocumentStore Store;
- JSONRPCDispatcher Dispatcher(llvm::make_unique<Handler>(Outs, Logs));
+ JSONRPCDispatcher Dispatcher(llvm::make_unique<Handler>(Out));
Dispatcher.registerHandler("initialize",
- llvm::make_unique<InitializeHandler>(Outs, Logs));
+ llvm::make_unique<InitializeHandler>(Out));
Dispatcher.registerHandler("shutdown",
- llvm::make_unique<ShutdownHandler>(Outs, Logs));
+ llvm::make_unique<ShutdownHandler>(Out));
Dispatcher.registerHandler(
"textDocument/didOpen",
- llvm::make_unique<TextDocumentDidOpenHandler>(Outs, Logs, Store));
+ llvm::make_unique<TextDocumentDidOpenHandler>(Out, Store));
// FIXME: Implement textDocument/didClose.
Dispatcher.registerHandler(
"textDocument/didChange",
- llvm::make_unique<TextDocumentDidChangeHandler>(Outs, Logs, Store));
+ llvm::make_unique<TextDocumentDidChangeHandler>(Out, Store));
Dispatcher.registerHandler(
"textDocument/rangeFormatting",
- llvm::make_unique<TextDocumentRangeFormattingHandler>(Outs, Logs, Store));
+ llvm::make_unique<TextDocumentRangeFormattingHandler>(Out, Store));
Dispatcher.registerHandler(
"textDocument/formatting",
- llvm::make_unique<TextDocumentFormattingHandler>(Outs, Logs, Store));
+ llvm::make_unique<TextDocumentFormattingHandler>(Out, Store));
while (std::cin.good()) {
// A Language Server Protocol message starts with a HTTP header, delimited
@@ -89,6 +90,10 @@ int main(int argc, char *argv[]) {
// Finally, execute the action for this JSON message.
if (!Dispatcher.call(JSONRef))
Logs << "JSON dispatch failed!\n";
+
+ // If we're done, exit the loop.
+ if (Out.isDone())
+ break;
}
}
}
Modified: clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp?rev=294747&r1=294746&r2=294747&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp (original)
+++ clang-tools-extra/trunk/clangd/JSONRPCDispatcher.cpp Fri Feb 10 08:08:40 2017
@@ -15,10 +15,11 @@
using namespace clang;
using namespace clangd;
-void Handler::writeMessage(const Twine &Message) {
+void JSONOutput::writeMessage(const Twine &Message) {
llvm::SmallString<128> Storage;
StringRef M = Message.toStringRef(Storage);
+ std::lock_guard<std::mutex> Guard(StreamMutex);
// Log without headers.
Logs << "--> " << M << '\n';
Logs.flush();
@@ -29,7 +30,7 @@ void Handler::writeMessage(const Twine &
}
void Handler::handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) {
- Logs << "Method ignored.\n";
+ Output.logs() << "Method ignored.\n";
// Return that this method is unsupported.
writeMessage(
R"({"jsonrpc":"2.0","id":)" + ID +
@@ -37,7 +38,7 @@ void Handler::handleMethod(llvm::yaml::M
}
void Handler::handleNotification(llvm::yaml::MappingNode *Params) {
- Logs << "Notification ignored.\n";
+ Output.logs() << "Notification ignored.\n";
}
void JSONRPCDispatcher::registerHandler(StringRef Method,
Modified: clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h?rev=294747&r1=294746&r2=294747&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h (original)
+++ clang-tools-extra/trunk/clangd/JSONRPCDispatcher.h Fri Feb 10 08:08:40 2017
@@ -13,15 +13,42 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/YAMLParser.h"
+#include <mutex>
namespace clang {
namespace clangd {
+/// Encapsulates output and logs streams and provides thread-safe access to
+/// them.
+class JSONOutput {
+public:
+ JSONOutput(llvm::raw_ostream &Outs, llvm::raw_ostream &Logs)
+ : Outs(Outs), Logs(Logs) {}
+
+ /// Emit a JSONRPC message.
+ void writeMessage(const Twine &Message);
+
+ /// Get the logging stream.
+ llvm::raw_ostream &logs() { return Logs; }
+
+ /// Use this to indicate that the output stream should be closed and the
+ /// process should terminate.
+ void setDone() { Done = true; }
+ bool isDone() const { return Done; }
+
+private:
+ llvm::raw_ostream &Outs;
+ llvm::raw_ostream &Logs;
+
+ bool Done = false;
+
+ std::mutex StreamMutex;
+};
+
/// Callback for messages sent to the server, called by the JSONRPCDispatcher.
class Handler {
public:
- Handler(llvm::raw_ostream &Outs, llvm::raw_ostream &Logs)
- : Outs(Outs), Logs(Logs) {}
+ Handler(JSONOutput &Output) : Output(Output) {}
virtual ~Handler() = default;
/// Called when the server receives a method call. This is supposed to return
@@ -33,11 +60,10 @@ public:
virtual void handleNotification(llvm::yaml::MappingNode *Params);
protected:
- llvm::raw_ostream &Outs;
- llvm::raw_ostream &Logs;
+ JSONOutput &Output;
- /// Helper to write a JSONRPC result to Outs.
- void writeMessage(const Twine &Message);
+ /// Helper to write a JSONRPC result to Output.
+ void writeMessage(const Twine &Message) { Output.writeMessage(Message); }
};
/// Main JSONRPC entry point. This parses the JSONRPC "header" and calls the
Modified: clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp?rev=294747&r1=294746&r2=294747&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp (original)
+++ clang-tools-extra/trunk/clangd/ProtocolHandlers.cpp Fri Feb 10 08:08:40 2017
@@ -17,7 +17,7 @@ void TextDocumentDidOpenHandler::handleN
llvm::yaml::MappingNode *Params) {
auto DOTDP = DidOpenTextDocumentParams::parse(Params);
if (!DOTDP) {
- Logs << "Failed to decode DidOpenTextDocumentParams!\n";
+ Output.logs() << "Failed to decode DidOpenTextDocumentParams!\n";
return;
}
Store.addDocument(DOTDP->textDocument.uri, DOTDP->textDocument.text);
@@ -27,7 +27,7 @@ void TextDocumentDidChangeHandler::handl
llvm::yaml::MappingNode *Params) {
auto DCTDP = DidChangeTextDocumentParams::parse(Params);
if (!DCTDP || DCTDP->contentChanges.size() != 1) {
- Logs << "Failed to decode DidChangeTextDocumentParams!\n";
+ Output.logs() << "Failed to decode DidChangeTextDocumentParams!\n";
return;
}
// We only support full syncing right now.
@@ -91,7 +91,7 @@ void TextDocumentRangeFormattingHandler:
llvm::yaml::MappingNode *Params, StringRef ID) {
auto DRFP = DocumentRangeFormattingParams::parse(Params);
if (!DRFP) {
- Logs << "Failed to decode DocumentRangeFormattingParams!\n";
+ Output.logs() << "Failed to decode DocumentRangeFormattingParams!\n";
return;
}
@@ -108,7 +108,7 @@ void TextDocumentFormattingHandler::hand
llvm::yaml::MappingNode *Params, StringRef ID) {
auto DFP = DocumentFormattingParams::parse(Params);
if (!DFP) {
- Logs << "Failed to decode DocumentFormattingParams!\n";
+ Output.logs() << "Failed to decode DocumentFormattingParams!\n";
return;
}
Modified: clang-tools-extra/trunk/clangd/ProtocolHandlers.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/ProtocolHandlers.h?rev=294747&r1=294746&r2=294747&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/ProtocolHandlers.h (original)
+++ clang-tools-extra/trunk/clangd/ProtocolHandlers.h Fri Feb 10 08:08:40 2017
@@ -25,8 +25,7 @@ namespace clangd {
class DocumentStore;
struct InitializeHandler : Handler {
- InitializeHandler(llvm::raw_ostream &Outs, llvm::raw_ostream &Logs)
- : Handler(Outs, Logs) {}
+ InitializeHandler(JSONOutput &Output) : Handler(Output) {}
void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
writeMessage(
@@ -40,19 +39,16 @@ struct InitializeHandler : Handler {
};
struct ShutdownHandler : Handler {
- ShutdownHandler(llvm::raw_ostream &Outs, llvm::raw_ostream &Logs)
- : Handler(Outs, Logs) {}
+ ShutdownHandler(JSONOutput &Output) : Handler(Output) {}
void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override {
- // FIXME: Calling exit is rude, can we communicate to main somehow?
- exit(0);
+ Output.setDone();
}
};
struct TextDocumentDidOpenHandler : Handler {
- TextDocumentDidOpenHandler(llvm::raw_ostream &Outs, llvm::raw_ostream &Logs,
- DocumentStore &Store)
- : Handler(Outs, Logs), Store(Store) {}
+ TextDocumentDidOpenHandler(JSONOutput &Output, DocumentStore &Store)
+ : Handler(Output), Store(Store) {}
void handleNotification(llvm::yaml::MappingNode *Params) override;
@@ -61,9 +57,8 @@ private:
};
struct TextDocumentDidChangeHandler : Handler {
- TextDocumentDidChangeHandler(llvm::raw_ostream &Outs, llvm::raw_ostream &Logs,
- DocumentStore &Store)
- : Handler(Outs, Logs), Store(Store) {}
+ TextDocumentDidChangeHandler(JSONOutput &Output, DocumentStore &Store)
+ : Handler(Output), Store(Store) {}
void handleNotification(llvm::yaml::MappingNode *Params) override;
@@ -72,10 +67,8 @@ private:
};
struct TextDocumentRangeFormattingHandler : Handler {
- TextDocumentRangeFormattingHandler(llvm::raw_ostream &Outs,
- llvm::raw_ostream &Logs,
- DocumentStore &Store)
- : Handler(Outs, Logs), Store(Store) {}
+ TextDocumentRangeFormattingHandler(JSONOutput &Output, DocumentStore &Store)
+ : Handler(Output), Store(Store) {}
void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override;
@@ -84,9 +77,8 @@ private:
};
struct TextDocumentFormattingHandler : Handler {
- TextDocumentFormattingHandler(llvm::raw_ostream &Outs,
- llvm::raw_ostream &Logs, DocumentStore &Store)
- : Handler(Outs, Logs), Store(Store) {}
+ TextDocumentFormattingHandler(JSONOutput &Output, DocumentStore &Store)
+ : Handler(Output), Store(Store) {}
void handleMethod(llvm::yaml::MappingNode *Params, StringRef ID) override;
More information about the cfe-commits
mailing list